assert(Base<T1, T2>::test()); == "assert" passed 2 arguments, but takes just 1. g++ bug?
-
hi,
ich nutze g++ 3.4.2 (mingw) und habe folgenden code:
template<class T1, class T2> class Base { public: bool test() { return true; } }; template<class T1, class T2> class Derived : public Base<T1, T2> { public: void test2() { assert(Base<T1, T2>::test()); } };Dabei krieg ich die Meldung: "assert" passed 2 arguments, but takes just 1
Wenn ich allerdings
bool b = Base<T1, T2>::test(); assert(b);schreibe dann funktioniert es.
ist ein bug im compiler, oder?
-
Bei mir im BCB 6 und Dev C++ funktioniert es ohne Problem

-
-- quatsch --
-
Hallo,
die Lösung ist einfach und heißt Klammern:assert( (Base<T1, T2>::test()) );Das Problem besteht, da assert ein Makro ist und Makros nur dumme Textersetzung sind die von sowas wie Templates keine Ahnung haben. Der Präprozessor erkennt nicht, dass <T1, T2> eine Templateparameterliste ist und behandelt dies deshalb nicht zusammenhängend. Stattdessen zerlegt er das Ganze sinnlos in Tokens und dabei sieht er dann Base < T1 als erstes Argument und , T2 >::test() als zweites Argument an. Und das passt nicht zum assert-Makro, da dieses ja nur ein Argument erwartet.
-
oh man, da wäre ich nie drauf gekommen. jetzt hab ichs gerafft.

vielen dank hume!der visual c++ compiler sagt einfach nur
Zu viele übergebene Parameter für das Makro 'assert'
compiliert dann aber trotzdem weiter. *lol*

ich habe noch ne kleine andere frage.
bei visual c++ 7.1 konnte ich es immer so schreiben
assert(test());
ohne das Base<...>:: und deshalb kam es nie zu dem problem.
beim mingw muss ich das immer davor schreiben.
hält sich da visual c++ nicht an den standard?
-
matthias. schrieb:
bei visual c++ 7.1 konnte ich es immer so schreiben
assert(test());
ohne das Base<...>:: und deshalb kam es nie zu dem problem.
beim mingw muss ich das immer davor schreiben.
hält sich da visual c++ nicht an den standard?
Versuch's mal so:
template<class T1, class T2> class Derived : public Base<T1, T2> { using Base<T1, T2>::test; // ... };Gründe dafür gibt's in der FAQ(?) oder Forensuche.
-
bei visual c++ 7.1 konnte ich es immer so schreiben
assert(test());
ohne das Base<...>:: und deshalb kam es nie zu dem problem.
beim mingw muss ich das immer davor schreiben.
hält sich da visual c++ nicht an den standard?
Richtig. test ist ein Name aus der Basisklasse. Normalerweise werden Namen aus Basisklassen in abgeleiteten Klassen ja automatisch berücksichtigt. Bei Templatebasisklassen, die abhängig von einem Templateparameter sind (so wie hier -> Base ist abhängig von T1 und T2) gilt aber eine besondere Regel, die man umganssprachlich so formulieren könnte:
Unabhängige Namen (Namen die nicht von einem Template-Parameter abhängen) werden niemals in abhängigen Templatebasisklassen gesucht.
Schreibst du einfach nur test(), dann ist test ein unabhängiger Name (nirgendwo ist eine Abhängigkeit zum Typ T1 oder T2 zu erkennen). Ein konformer Compiler sucht test jetzt nur im Scope von Derived und in den darüberliegenden Namespace-Scopes. Nicht aber im Scope von Base. Deshalb kommt es zum Fehler.
Durch die Qualifikation mit Base<T1, T2> sagst du dem Compiler direkt in welchem Scope er test suchen soll. Eine andere Möglichkeit wäre die Qualifikation mit this->. this->test() gilt als abhängiger Name (this hängt von T1 und T2 ab, deshalb auch this->test). Und solche sucht der Compiler auch n abhängigen Basisklassen.