2014-01-07 7 views
6

Schauen Sie sich diesen Code an.Benennen Sie std :: vector in eine andere Klasse um, um sie zu überladen?

#include <vector> 

template<class ...Args> 
using other_vector = std::vector<Args...>; 

template<class T> 
void f(std::vector<T>&) {} 
template<class T> 
void f(other_vector<T>&) {} 

int main() 
{ 
    other_vector<int> b; 
    f(b); 
    return 0; 
} 

Es kompiliert nicht, weil f neu deklariert wird. Ich verstehe den Fehler vollkommen. Allerdings brauche ich eine zweite Klasse, die sich wie std::vector<T> verhält, aber als ein anderer Typ betrachtet wird, so dass eine Überladung, wie im obigen Beispiel, legal wäre.

Was könnte ich tun?

  • Lassen Sie die neue Klasse std::vector<T> als Basisklasse haben. Dies könnte funktionieren, aber nicht von Standardcontainern erben.
  • Lassen Sie die neue Klasse ein Member vom Typ std :: vector haben und dann alle Funktionen neu deklarieren, um die Funktionen des Members umzuleiten. Klingt nach viel Arbeit.

Jede bessere Alternative? C++ 11 oder C++ 14 erlaubt.

+6

Werfen Sie einen Blick auf 'BOOST_STRONG_TYPEDEF'. Wenn es nicht mit Vorlagen funktioniert, könnten Sie sich wahrscheinlich inspirieren lassen, etwas zu machen, das funktioniert. – chris

+1

Sind Sie sicher, dass Sie zwei Funktionen für fast den gleichen Typ benötigen? – StoryTeller

+0

Versuchen Sie die Vererbung. –

Antwort

17

Sie könnten mit dem Zuteiler zu verwirren versuchen:

template<class T> 
struct allocator_wrapper : T { using T::T; }; 

template<class T, class A = std::allocator<T>> 
using other_vector = std::vector<T, allocator_wrapper<A>>; 

Live example

+0

Clevere Idee ... Danke, das funktioniert. – Johannes

+0

'mit T :: T;' Whoa OO +1 – StoryTeller

+1

@Johannes Und falls Sie mehr von diesen verschiedenen Typen benötigen, fügen Sie einfach einen ganzzahligen Parameter zum 'allocator_wrapper' hinzu und Sie können eine beliebige Anzahl von ihnen haben ... :) –

0

Wenn Sie mehr als eine Kopie benötigen, können Sie es sich um eine Vorlage machen und eine int Vorlage arg für „Klon-Nummer“ nehmen

+0

Aber ich würde immer noch einen der beiden oben genannten Punkte verwenden müssen, mit den genannten Nachteilen? – Johannes

+0

@Johannes ist wahr, aber Sie können den Template-Parameter 'int' mit der Lösung kombinieren, die Sie für einen Klon haben, um ihn auf N zu erweitern –

0

Sie können Ihre Art wie folgt wickeln:

// N allow to have several 'version' of the same type T 
template <typename T, int N = 0> 
class WrapperType 
{ 
public: 
    WrapperType() = default; 
    WrapperType(const WrapperType&) = default; 
    WrapperType(WrapperType&&) = default; 

    template <typename ... Ts> 
    explicit WrapperType(Ts&& ... ts) : t(std::forward<Ts>(ts)...) {} 

    // implicit conversion 
    // you may prefer make them explicit or use name get(). 
    operator const T&() const { return t; } 
    operator T&() { return t; } 

private: 
    T t; 
}; 

Und so für Ihren Fall:

template<class T> 
using other_vector = WrapperType<std::vector<T>>; 
Verwandte Themen