Am besten gehen Sie durch eins nach dem anderen. Um Unklarheiten zu vermeiden, werde ich verschiedenen Template-Argument-Namen im Beispiel
template<class C, class signature> void f(signature C::*ptr) {}
Alle Zitate auf den neuesten Arbeitsentwurf des C++ 14-Standard beziehen verwenden.
Zuerst müssen wir verstehen, wie die Template-Parameter behandelt werden.
[temp.param]/3 Ein Typ-Parameter, deren Kennung nicht eine Ellipse definiert seine Kennung folgt
So Ihre Template-Definition hat zwei Parameter ein typedef-Name sein T
und die Unterschrift. Wenn signature
in dem Schablonenkörper verwendet wird, ist es daher gleichbedeutend mit dem typedef
typedef void signature(float, int);
Diese typedef verwendet werden können, einen Funktionszeiger Parameter, wie in Ihrem Beispiel zu erklären:
[dcl.fct ]/12 A typedef der Funktionstyp kann eine Funktion zu erklären, verwendet werden, jedoch soll keine Funktion
In den Parametern der te definiert werden mplate Funktion, die Sie schreiben signature T::*ptr
, mal sehen, was der Standard sagt über das Mitglied Zeiger:
[dcl.mptr]/1 In einer Erklärung T D
wo D
die Form hat
nested-name-specifier * attribute-specifier-seq_opt cv-qualifier-seq_opt D1
und die verschachtelte Name-Spezifizierer bezeichnet eine Klasse, und der Typ der -Kennung in der Deklaration ist abgeleitete-Deklarator-Typ-Liste T, dann ist der Typ der Kennung von D
abgeleitet-declarator-type-list cv-qualifier-seq Zeiger auf Mitglied der Klasse geschachtelte Namen-Spezifizierer des Typs T.
In unserem Beispiel T
ist signature
, die Funktion typedef und D
ist C::*ptr
.
Dies erklärt, welche Arten der Compiler für das Beispiel ja
void f(void(A::*ptr)(float, int));
@ Daniel Frey ableiten wird. Ich weiß, dass alles funktioniert. Ich frage: Warum funktioniert das? Wo kann ich im C++ - Standard lesen, dass so etwas richtig ist? –