Alternative zu initializer_list
-
Hallo,
Ich würde gerne dem Konstruktor einer Klasse beliebig viele Elemente des
gleichen Typs übergeben. In C++11 ist dies ja relativ einfach über initializer_list (so wie unten) möglich.Mein Kompiler unterstützt leider kein C++11 und deshalb wollte ich fragen ob
es trotzdem eine Möglichkeit gibt oder ob es nur die Möglichkeit gibt, meine Objekte zuvor in ein Vektor zu speichern und diesen danach dem Konstruktor zu übergeben.#include <iostream> #include <vector> #include<initializer_list> using namespace std; class Ausgabe{ public: void show(){ cout << var << "\n"; } Ausgabe(int varK) : var(varK) {} private: int var; }; class foo{ public: foo(initializer_list<Ausgabe> liste); void show(); private: vector<Ausgabe> storage; }; foo::foo(initializer_list<Ausgabe> liste){ storage.assign(liste); } void foo::show(){ cout << "Elemente:" << "\n"; for (auto element : storage){ element.show(); } } int main() { foo Ausgaben{ Ausgabe(1), Ausgabe(2), Ausgabe(3) }; Ausgaben.show(); }
-
Wenn die Elemente später sowieso wieder in einem Vector landen, sehe ich nichts was dagegen spricht gleich den Vector als const ref zu übergeben oder foo vorher zu initialisieren und dann eine Funktion "Add Ausgabe" aufzurufen.
-
Folgendes könnte interessant für dich sein: http://erdani.com/publications/inline_containers.html
-
Shade Of Mine schrieb:
Folgendes könnte interessant für dich sein: http://erdani.com/publications/inline_containers.html
Hübsche Idee.
-
Shade Of Mine schrieb:
Folgendes könnte interessant für dich sein: http://erdani.com/publications/inline_containers.html
Vielen Dank Shade Of Mine, funktioniert einwandfrei!
Ruvi schrieb:
Wenn die Elemente später sowieso wieder in einem Vector landen, sehe ich nichts was dagegen spricht gleich den Vector als const ref zu übergeben oder foo vorher zu initialisieren und dann eine Funktion "Add Ausgabe" aufzurufen.
Ja das ist sicher so, ich habe mich auch nur gefragt ob es eine ähnlich elegante Variante wie initializer_list gibt.
#ifndef __INLINE_CONTAINER_H__ #define __INLINE_CONTAINER_H__ #include <vector> #include <list> #include <deque> template < class T, class container = std::vector<T> > class inline_container : public container { public: inline_container() { } inline_container(inline_container &v) { this->swap(v); } explicit inline_container(const T &a) : container(1, a) { } inline_container &operator()(const T &a) { this->push_back(a); return *this; } }; template <class T> inline inline_container<T> make_vector(const T &a) { return inline_container<T>(a); } #endif#include <vector> #include <iostream> #include "InlineContainer.h" using namespace std; class foo{ public: foo(std::vector<Ausgabe> liste); void show(); private: std::vector<Ausgabe> storage; }; foo::foo(std::vector<Ausgabe> liste){ storage = liste; } void foo::show(){ cout << "Elemente:" << "\n"; for (auto element : storage){ element.show(); } } int main() { foo Ausgaben(make_vector(Ausgabe(1))(Ausgabe(2))(Ausgabe(3))); Ausgaben.show(); }
-
Hoselupf schrieb:
Ja das ist sicher so, ich habe mich auch nur gefragt ob es eine ähnlich elegante Variante wie initializer_list gibt.
Das trifft auf die
const referencedurchaus zu. Wenn dein Konstruktor vonfooso aussieht:foo(const std::vector<Ausgabe>& liste) : storage{ liste } { };... dann kannst du das Ganze einfach so aufrufen:
foo Ausgaben{ { 1, 2, 3 } }; Ausgaben.show();Der einzige Unterschied ist, dass du dem Kosntruktor hier eine Initializer List übergeben musst (doppelte geschweifte Klammern), die dann an den Konstruktor des
vectorweitergereicht wird. Ich halte das für eleganter als die - zugegebenermaßen pfiffige, aber nicht mehr zeitgemäße Lösung mit dem Funktions-Operator (die stammt noch aus Zeiten bevor es variadische Templates und Initializer Lists gab).Wenn du's optimal haben möchtest (aber mit kompliziertererem Code), kannst du es auch mit "Perfect Forwarding" versuchen:
class foo{ ... template <typename... ARGS> foo(ARGS&&... args) : storage{ { std::forward<ARGS>(args)... } } { }; ... } ... foo Ausgaben{ 1, 2, 3 }; Ausgaben.show();... nur so als zwei Alternativen, die weniger Code benötigen

Gruss,
Finnegan