2015-05-09 7 views
5

Der folgende Code funktioniert gut, aber ich kann nicht herausfinden, basierend auf welchen Punkten des C++ - Standards sollte es gültig sein.C++ - Vorlagen mit Zeiger auf Member-Funktion von Signatur und Typ

template< class C, class signature > 
void f(signature C::*ptr) { } 

Wenn C = A und signature = void(float, int), wird die Funktion f

void f(void(A::*ptr)(float, int)) 

sein, auf deren Basis Teile der Norm, wird die Vorlage auf die letztere gelten?

+0

@ 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? –

Antwort

4

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));