T C::* zu habgierig?
-
folgender Code:
struct X { int a; int f(); }; void foo(int X::*) {} template<typename T, typename C> void foo2(T C::*) {} void bar() { foo(&X::a); foo2(&X::a); foo(&X::f); // geht schief foo2(&X::f); // sollte auch schiefgehen, tut es aber nicht }Eigentlich erwarte ich, dass der Compiler hier ein Problem wie angegeben findet. Visual C++ 2005 und Comeau C++ sind da allerdings anderer Meinung. Gibts einen anderen Weg der Deklaration (d.h. ohne noch eine Überladung für Memberfunktionen anbieten zu müssen oder etwas anderes Umständliches - das wäre ja kein Problem), so dass die Funktion wirklich nur für Zeiger auf Member existiert?
-
Nö, das geht schon OK. Obwohl ich auch erstmal Augen machte als mein VC 2005 SP1 das gefressen hat.
T ist in dem Fall dann einfach "int __thiscall(void)"
:struct X { int f(){return 42;} }; template<typename T, typename C> void test(T C::*) { printf("T: %s\n", typeid(T).name()); } int main() { test(&X::f); // passt schon so, ist nur aufn ersten blick nicht erkennbar wenn man noch nicht weiss was passieren wird }
-
Ja aber bist du da vollkommen abgesichert? Du hast ja eben noch den int dort. Was ist wenn da ein std::string in der struct steht? Meiner Meinung brauchst du noch einen Parameter, der dir die typisierte strukture übergibt. Oder spielt da der Retourparameter keine Rolle?
-
Der gcc frisst das zumindest nicht.
der sagt bei hustbaers beispiel:
test.cpp:17: error: no matching function for call to `test(int (X::*)())'
ich vermute hier eine nonstandard extension beim vc
-
otze schrieb:
Der gcc frisst das zumindest nicht.
der sagt bei hustbaers beispiel:
test.cpp:17: error: no matching function for call to `test(int (X::*)())'
ich vermute hier eine nonstandard extension beim vc
Das hatte ich auch gedacht (eher ein Compilerbug - denn Erweiterungen hab ich abgeschaltet) aber auch der Online Comeau Compiler nimmt es in allen Versionen. Es ist auch recht nutzlos, denn mit dem übergebenen Pointer selbst kann ich nicht sinnvoll weiterarbeiten. Es wird noch besser:
foo2<int>(&X::f); foo2<int,X>(&X::f);werden beide abgelehnt. Scheint also doch ein Bug sein.
-
Sorry muss mich hier mal anhängen.
Verstehe nämlich die Syntax und deren Zweck nicht.
Was soll denn dieser Code bewirken?
Habe mir das Beispiel gebastelt.struct Test { int a; void f(); }; void foo(int Test::* b) // was ist denn das für ein Paramter???? { std::cout << b; } int _tmain(int argc, _TCHAR* argv[]) { foo(&Test::a); }Bei mir kommt 1 raus ???
-
Muss mich korrigieren: es müsste
foo2<int(),X>(&X::f);heißen und das funktioniert dann auch. Muss ich für meine Zwecke eben doch nochmal nur für Zeiger auf Memberfunktionen spezialisieren. Es gibt ja einen ähnlichen Fall, wo ein einfacher Funktionstyp für Memberfunktionen benutzt wird:
typedef void foo(); struct X { foo bar; // deklariert die nichtstatische Memberfunktion void X::bar() };sehr unintuitiv - imo hätte man das anders lösen sollen.
-
@templäd
das ist auch nicht die richtige nutzung.man nutzt den zeiger eigentlich für sowas:
template<class Class, class Type> void foo(const Class& object,int Class::* memberpointer) { std::cout<<object.*memberpointer; }; struct Test { int bar; }; int main() { Test test; test.bar=35; foo(test,&Test::bar); };
-
@templäd: Memberfunktionspointer können implizit in bool konvertiert werden (Ergebnis entspricht dem Vergleich mit einem Nullpointer dieses Typs). Und für bool existiert eine Überladung des Operators << mit ostream...
dein
foo(&Test::a);ist daher so etwas wie:
std::cout << (&Test::a != 0);und da kommt natürlich true (1) heraus.