Einfügen einer Variable argument-Liste in einen Vektor?
Verzeihen Sie mir, wenn dies wurde bereits beantwortet, als ich konnte ihn nicht finden...
Grundsätzlich habe ich ein Objekt treffen muss, um eine Variable argument-Liste im Konstruktor und speichert die Argumente, die in einem Vektor. Wie kann ich die initialisieren einen Vektor von einem der Argumente eine Variable Konstruktor?
class GenericNode {
public:
GenericNode(GenericNode*... inputs) {
/* Something like... */
//inputs_.push_back(inputs)...;
}
private:
std::vector<GenericNode*> inputs_;
};
- Es gibt einige ungültige syntax in deinem Beispiel. Was genau versuchst du zu Fragen?
- verwenden
std::initializer_list<GenericNode*>
. - Sorry. Um zu klären, wie verwende ich die argument-Liste zu füllen std::vector? @MooingDuck, guck ich in die std::initializer_list. Danke.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den besten Sache wäre die Verwendung einer Initialisierungsliste
Dem am nächsten, was Sie bereits haben, mit C++11 ist die Verwendung des Vektors initializer_list:
Und hier ist ein C++11-version ohne initializer_lists überhaupt. Es ist hässlich und kompliziert und erfordert Funktionen fehlt vielen Compilern. Verwenden Sie die Initialisierungsliste
Unabhängig von alles, was, die ich weiß nicht, ob diejenigen sind, besitzen die Zeiger oder nicht. Wenn Sie sind, verwenden Sie
std::unique_ptr
statt.template<typename... T> GenericNode(T*... inputs) :inputs_{ inputs... } { }
näher zu dem, was er bereits hat? ich gehe immer noch mitstd::initializer_list<GenericNode*>
obwohl.Ts
es fügt eine'0'
auf das array. Allerdings, wenn Sie keine Eingänge, das ist das gleiche wiechar t[] = {}
ungültig, so dass wir tack auf einem extra'0'
so gibt es immer mindestens ein element in das temporäre array....
ist garantiert Auspacken in Ordnung, aber ich würde nicht schwören, dass es so ist.Funktioniert das nicht, weil Sie nicht erweitern kann ein parameter-pack als eine Aussage, die nur in bestimmten Kontexten wie eine Funktion argument-Liste oder der Initialisierer-Liste.
Auch Ihr Konstruktor Signatur ist falsch, wenn Sie versuchen zu schreiben, ein variadic template muss es eine Vorlage!
Wenn Sie schreiben, Ihr Konstruktor Signatur richtig, die Antwort ist einfach: konstruieren Sie den Vektor mit dem expansion pack:
(Man könnte stattdessen haben Sie in den Konstruktor Körper mit:
aber die coolen kids member-Initialisierungen nicht Zuweisung im Konstruktor Körper.)
Der Nachteil dieser Lösung ist, dass die template-Konstruktor akzeptiert jede Art von Zeiger-Argumente an, wird dann aber zu einem Fehler, wenn Sie versuchen zu bauen, Vektor, wenn die Argumente sind nicht konvertierbar
GenericNode*
. Sie könnte fixieren Sie die Vorlage nur annehmenGenericNode
Zeiger, aber das ist, was geschieht automatisch, wenn Sie das tun, was die anderen Antworten vorschlagen und machen den Konstruktor nehmenstd::initializer_list<GenericNode*>
, und dann Sie brauchen keine hässlichenenable_if
SFINAE tricks.Können Sie nicht verwenden Sie eine Variable Argumentliste, es sei denn, es ist eine Vorlage, Sie können, wie gesagt, verwenden Sie eine initializer_list wie diese:
Anderen Weg, es zu tun:
Beispiel von C++11 Wahrheiten sieht einfach genug...;)
Keine vollständige Lösung, aber könnte Ihnen einige Ideen.
b1
undb2
Beispiele, aber die OP machen willBlob b3{ "Circle", "Triangle", "Square" };
und IhreBlob
Konstruktor kann das nicht tun, weil Sie Wert-Initialisierung für_v
. Wenn Sie es ändern, verwenden list-Initialisierung für_v
es unterstützen würde, was der OP machen will.Ich schrieb vor kurzem die folgende Funktion, die einen string mit
{1} , {2} , {3} ... in es und ersetzt die Liste von Argumenten. Ich lief in das gleiche problem, bis ich beschlossen, damit der compiler work it out für sich selbst mit dem auto-keyword.
Das ist scheinbar gut genug, solange die Arten line-up richtig.
In diesem Fall verwende ich nur std::string ganz.
Ich denke, das ist eine elegante Technik, aber es kann Nachteile haben.