2009-03-30 4 views
8

Ich möchte eine Nachricht mit unbekannter Länge oder Anzahl von Argumenten konstruieren. Ich nahm eine einfache Vorlage wieWie man verschiedene Template-Typen in einen Vektor einfügt

template <typename T> class Argument { 
public: 
    int size; 
    int type; 
    T data; 
}; 

und mit einigen überlastet

addMessage (int value) { 
    Argument<int> *a = new Argument<int>; 
    vec.push_back(a); 
} 

(gleiche für Streich- und so weiter) Ich versuche, alles in einen Vektor zu schieben. Ich versuchte

std::vector<Argument* > vec; 
std::vector<Argument<typename T>* > vec; 
std::vector<Argument<>* > vec; 

, aber nichts davon scheint zu arbeiten. Gibt es eine Möglichkeit, dies zu tun? Danke im Voraus.

Antwort

13

Option 1: Stellen Sie sicher, dass alle verschiedenen Arten von Argumenten von einer Basisklasse abgeleitet sind und Zeiger auf diese Klasse verwenden. Beachten Sie, dass diese Option in Bezug auf die Speicherverwaltung riskant ist. Vielleicht möchten Sie es sicherer machen, indem Sie boost :: shared_ptr anstelle von Zeigern verwenden. Andernfalls müssen Sie manuell bereinigen, wenn ein Element aus dem Vektor entfernt wird.

Option 2 (mein persönlicher Favorit): Boost.Variant verwenden, um eine typedef aller möglichen Argumenttypen zu machen und dass typedef als Argument Typ in std :: vector

typedef boost::variant<ArgumentType1, ArgumentType2, ArgumentType3> ArgumentType; 
std::vector<ArgumentType> vec; 
+0

Sieht so aus, als hätte ich mich geirrt, als ich dachte, Vorlagen würden "alle Typen" zur Hand haben. Da in diesem Projekt kein Boost verwendet wird, bleibe ich bei der Vererbung. thx – DaClown

+0

'std :: variant' ist seit C++ 17 verfügbar. http://en.cppreference.com/w/cpp/utility/variant – biowep

4

könnten Sie boost :: Variante (http://www.boost.org/doc/libs/1_38_0/doc/html/variant.html)
oder boost :: any (http://www.boost.org/doc/libs/1_38_0/doc/html/any.html) Typen

oder void * - hässlich und nicht typsicher
oder eigenen generischen Typen implementieren, die eine Schnittstelle haben und unterschiedliche Vorlagenimplementierung und speichert Zeiger auf dieser Schnittstelle.

Aber ich bin nicht sicher, dass die Verwendung ähnlicher Typen gutes Design ist.

6

Der einfachste Weg, dies zu tun wäre Es muss eine Basis-Argument-Klasse sein, die nicht als Vorlage dient, und dann müssen die spezifischen Datentypen daraus abgeleitet werden. (Sie könnten sogar die Vorlagenversion direkt von der Basisklasse ableiten und nur diese beiden Klassen verwenden.) Dann speichern Sie sie als Zeiger in einem Vektor.

Dies erfordert einige Funktionen, um auf die Argumentwerte zuzugreifen und alle erforderlichen Konvertierungen durchzuführen.