Zeiger auf geerbtes, templateparameterabhängiges Memberobjekt [erledigt]
-
Folgender kurzer Code:
template <typename T> struct foo { T data; }; template<typename T> struct bar: public foo<T> { typedef foo<T> Super; void some_func() { T* ptr = & (Super::data); } }; int main() { bar<int> b; b.some_func(); }Gibt den Fehler:
11: error: cannot convert ‘int foo<int>::*’ to ‘int*’ in initialization
Wie kann der Compiler aus dem Ausdruck&(Super::data)etwas vom Typ‘int foo<int>::*’herauslesen? Mir ist klar, dass ich auch einfach&(this->data)schreiben kann und dann geht's, aber ich möchte wissen, warum meine Schreibweise nicht funktioniert.Wenn ich das 1:1 ohne die Templates mache, geht das schließlich auch:
struct foo { int data; }; struct bar: public foo { typedef foo Super; void some_func() { int* ptr = & (Super::data); } };
-
Der Compiler interpretiert das fälschlicherweise als "Pointer-to-member", ähnlich wie ein Memberfunktionszeiger. Der speichert den relativen Offset zur Klasse, für den Zugriff benötigst du ein Objekt.
Soweit ich weiss, ist aber
& (Super::data)für einen Pointer-to-member syntaktisch nicht korrekt, die Klammern dürfen nicht stehen. Der Code mit Klammern sollte also funktionieren, unter MSVC++ und Comeau Online tut er das auch. Ich vermute einen Compilerbug in g++.
-
Nexus schrieb:
Der Compiler interpretiert das fälschlicherweise als "Pointer-to-member", ähnlich wie ein Memberfunktionszeiger. Der speichert den relativen Offset zur Klasse, für den Zugriff benötigst du ein Objekt.
Soweit ich weiss, ist aber
& (Super::data)für einen Pointer-to-member syntaktisch nicht korrekt, die Klammern dürfen nicht stehen. Der Code mit Klammern sollte also funktionieren, unter MSVC++ und Comeau Online tut er das auch. Ich vermute einen Compilerbug in g++.Danke für den Test auf anderen Compilern. Ich war schon sehr verwirrt, wie der zu dieser Interpretation kommt. Ich habe auch mal den intel-Compiler drauf losgelassen und der schluckt es auch. Hätte ich vielleicht gleich tun sollen, aber eigentlich gehe ich bei Standardfragen immer davon aus, dass eher der g++ recht hat :p .
Dann ist das Thema wohl schon erledigt und ich werde mal einen Bugreport aufsetzen.
-
Nexus schrieb:
Soweit ich weiss, ist aber
& (Super::data)für einen Pointer-to-member syntaktisch nicht korrekt, die Klammern dürfen nicht stehen.Das kann ich übrigens nach etwas Standardlesen bestätigen. Die Passage ist sogar extrem eindeutig:
C++ Standard 5.3.1-3 schrieb:
A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses. [ Note: that is, the expression &(qualified-id), where the qualified-id is enclosed in parentheses, does not form an expression of type “pointer to member.” Neither does qualified-id, because there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to member function” as there is from an lvalue of function type to the type “pointer to function” (4.3). Nor is &unqualified-id pointer to member, even within the scope of the unqualified-id’s class. — end note ]
Hervorhebung durch mich.