Verweis auf nicht-statischen Member (template,using,ctor,unwichtig/komisch)
-
tag.
der fehler ist nicht besonders schwerwiegend, aber er regt mich einfach auf.
ich weiß nicht nach was ich suchen soll, um das thema im forum zu finden.folgender abschnitt des quellcodes wird nicht verändert:
#include <list> template< class P > class TMsg { public: typedef int code_t; typedef P param_t; private: code_t cv; param_t pv; public: code_t const get_code() const { return cv; } param_t const get_param() const { return pv; } public: TMsg() : cv(0), pv(0) {} TMsg( TMsg const &r ) : cv(r.cv), pv(r.pv) {} TMsg( code_t c, param_t p ) : cv(c), pv(p) {} ~TMsg() {} };jetzt kommt erstmal die "class Test" und "main()", wie ich mir vorstelle, dass sie funktionieren sollten.
diese version wird KOMPILIERT!class Test { public: typedef TMsg<Test const*> msg_t; typedef std::list< msg_t > protocol_t; struct MSG { enum { UNKNOWN_ERROR, INVALID_METHOD, MOVE_MOUSE }; }; public: void report( protocol_t &prot ) { prot.push_back( msg_t( MSG::UNKNOWN_ERROR, this ) ); //!! } }; int main() { Test t; Test::protocol_t prot; t.report( prot ); return 0; };jetzt soll "class Test" aber von einer basisklasse abgeleitet werden, die die definition der "struct enum MSG", "typename msg_t" und "typename protocol_t" schon mitbringt und weiter über virtuelle methoden verfügt.
beispiel für die basisklasse und die resultierende "main()":class Base { public: typedef TMsg<Base const*> msg_t; typedef std::list< msg_t > protocol_t; struct MSG { enum { UNKNOWN_ERROR, INVALID_METHOD, MOVE_MOUSE }; }; virtual int do_sth() { return -1; } virtual ~Base() {} }; /* ... definition von "template class TTest" */ int main() { typedef TTest<Base> Test; Test t; Test::protocol_t prot; t.report( prot ); return 0; };schreibt man "class Test" zu "template class TTest" um, bekommt man folgendes:
( wird NICHT KOMPILIERT! )template < class B > class TTest : public B { public: using typename B::msg_t; using typename B::protocol_t; using typename B::MSG; public: void report( protocol_t &prot ) { prot.push_back( msg_t( MSG::UNKNOWN_ERROR, static_cast<B*>(this) ) ); //!! } };Visual C++ 2008 EE meldet dann folgenden Fehler:
1>main.cpp(75) : error C2597: Ungültiger Verweis auf nicht-statischen Member 'TTest<B>::msg_t' 1> with 1> [ 1> B=Base 1> ] 1> main.cpp(74): Bei der Kompilierung der Klassen-template der void TTest<B>::report(std::list<_Ty> &)-Memberfunktion 1> with 1> [ 1> B=Base, 1> _Ty=Base::msg_t 1> ] 1>main.cpp(105): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "TTest<B>". 1> with 1> [ 1> B=Base 1> ]ich hab den fehler bereits behoben (durch ausprobieren)
und zwar hab ich die konstruktion der "msg" einfach aus dem ausdruck genommen.
( wird KOMPILIERT! )template < class B > class TTest : public B { public: using typename B::msg_t; using typename B::protocol_t; using typename B::MSG; public: void report( protocol_t &prot ) { msg_t msg( MSG::UNKNOWN_ERROR, static_cast<B*>(this) ); prot.push_back( msg ); //!! } };trotzdem stellt sich die frage, warum die vorherige version nicht funktioniert hat...
tests mit anderen compileren:
Visual C++ 6.0 kompiliert genauso, nur die fehlermeldung ist anders:
C:\prog\eigene\VCPP\Rechner2x2_4\ctor_tst_2008_10_09\main.cpp(74) : error C2064: Ausdruck ergibt keine Funktion C:\prog\eigene\VCPP\Rechner2x2_4\ctor_tst_2008_10_09\main.cpp(73) : Bei der Kompilierung der Member-Funktion 'void __thiscall TTest<class Base>::report( class std::list<class TMsg<class Base const *>, class std::allocator<class TMsg<class Base const *> > > &)' der Klassenvorlagemit Dev-C++ 4.9.9.2 funktionieren beide template versionen nicht.
mit OpenWatcom 1.6 funktioniert gar nichts.