error: request for member 'push_back' is ambiguous
-
Hallo,
ich würde gerne mehrfach von einer Klasse erben, wie etwa im folgenden
Beispiel:#include <iostream> #include <vector> struct Foo{ Foo(int i) : i(i){} int i; }; struct Bar{ Bar(int j) : j(j){} int j; }; class CVector : public std::vector<Foo*>, public std::vector<Bar*>{ }; int main(){ CVector vec; vec.push_back(new Foo(1)); vec.push_back(new Bar(2)); }
Ich weiß, dass man nicht von std::vector erben soll, weil dieser keinen virtuellen Destruktor hat. Wegen Code-Reduktion tue ich es trotzdem.
Jetzt kriege ich einen Compiler-Fehler:
test.cpp: In function 'int main()':
test.cpp:20:6: error: request for member 'push_back' is ambiguous
/opt/local/include/gcc45/c++/bits/stl_vector.h:741:7: error: candidates are: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = Bar*, _Alloc = std::allocator<Bar*>, value_type = Bar*]
/opt/local/include/gcc45/c++/bits/stl_vector.h:741:7: error: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = Foo*, _Alloc = std::allocator<Foo*>, value_type = Foo*]
test.cpp:21:6: error: request for member 'push_back' is ambiguous
/opt/local/include/gcc45/c++/bits/stl_vector.h:741:7: error: candidates are: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = Bar*, _Alloc = std::allocator<Bar*>, value_type = Bar*]
/opt/local/include/gcc45/c++/bits/stl_vector.h:741:7: error: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = Foo*, _Alloc = std::allocator<Foo*>, value_type = Foo*]Leider verstehe ich nicht warum, da (meiner Meinung nach) nur eine der Signaturen passt. Dies passiert auch wenn ich die Objekte direkt (ohne Pointer) speichere.
Ich weiß, dass ich es wie folgt lösen kann:
vec.std::vector<Foo*>::push_back(new Foo(1)); vec.std::vector<Bar*>::push_back(new Bar(2));
allerdings möchte ich etwa sowas:
class CVector : public std::vector<Foo*>, public std::vector<Bar*>{ public: template<typename T> void add(T* t){ // ... push_back(t); } }; int main(){ CVector vec; vec.add(new Foo(1)); vec.add(new Bar(2)); }
Also ein "Behandele sie gleich, aber speichere sie danach im passenden Vector"
Gruß,
MaPoX
-
Natürlich könnte ich etwas machen wie:
template<typename T> void add(T* t){ // .. typedef std::vector<T*> vector_type; this->vector_type::push_back(t); } };
Allerdings funktioniert das in folgendem Fall nicht mehr:
struct FooBar : public Foo{ FooBar(int i) : Foo(i){} };
vec.add(new FooBar(3));
weil es ja eine abgeleitete Klasse ist.
test.cpp: In member function 'void CVector::add(T*) [with T = FooBar]':
test.cpp:32:23: instantiated from here
test.cpp:23:3: error: 'CVector::add(T*) [with T = FooBar]::vector_type' is not a base of 'CVector'
-
MaPoX schrieb:
Ich weiß, dass man nicht von std::vector erben soll, weil dieser keinen virtuellen Destruktor hat. Wegen Code-Reduktion tue ich es trotzdem.
Nur wegen Code-Reduktion vererbt man nie. Und wer es doch tut, ist Manns genug, die Konsequenzen zu tragen.
Geh einfach den richtigen Weg und setze Komposition statt Vererbung ein. Also die beiden Container als Membervariablen halten.
-
Nexus schrieb:
MaPoX schrieb:
Ich weiß, dass man nicht von std::vector erben soll, weil dieser keinen virtuellen Destruktor hat. Wegen Code-Reduktion tue ich es trotzdem.
Nur wegen Code-Reduktion vererbt man nie. Und wer es doch tut, ist Manns genug, die Konsequenzen zu tragen.
Eigentlich wollte ich sagen, dass ich hier std::vector verwende und nicht eine
Klasse mit virtuellem Destruktor wie in WirklichkeitNexus schrieb:
Geh einfach den richtigen Weg und setze Komposition statt Vererbung ein. Also die beiden Container als Membervariablen halten.
Du meinst also etwas wie:
class CVector { public: void push_back(Foo* foo){ foo_vector.push_back(foo); } void push_back(Bar* bar){ bar_vector.push_back(bar); } template<typename T> void add(T* t){ // .. push_back(t); } private: std::vector<Foo*> foo_vector; std::vector<Bar*> bar_vector; };
Dann werd ich mich mal mit den zusätzlichen push_back-Funktionen anfreunden.
THX Nexus