2016-05-17 12 views
1
void func1(int){} 
void func2(char){} 

template <typename T> void (*p)(T); // error 
p = func1; 
p = func2; 

Warum können wir nicht einen Zeiger wie definieren?C++: Funktionszeiger mit Vorlage

Antwort

0

Dank @SergeyA und @Brians Hilfe, löste ich das Problem und bearbeite meine Antwort hier.

template<typename T> void (*p)(T): in diesem Fall ist p eine variable Vorlage (C++ 14). So können wir p wie folgt verwenden:

p<int> = func1; 
p<char> = func2; 

template<class T> using p = void (*)(T): in diesem Fall p ist eine Art von Typ (es ist wie typedef aber wir können nicht typedef für alias Vorlage verwenden). Was bedeutet, dass wir es so verwenden sollte:
jeder Block Umfang

p<int> x1 = func1; 
p<char> x2 = func2; 

Btw, beide sind template declaration, so können wir sie nicht setzen.

4

Sie können es wie folgt tun:

template<class T> using p = void (*)(T); 

void f(int); 
p<int> x = &f; 
+0

Downvote? Kann der ehrenwerte Downvoter bitte erklären, was das Problem mit meiner Antwort ist? – SergeyA

+0

Wahrscheinlich das OP, weil er "p = func1" schreiben wollte, ohne irgendwelche Template-Argumente. – kfsone

+0

@kfsone, das wäre sowieso nicht möglich. – SergeyA

3

C++ 14 erlaubt tatsächlich variable Vorlagen, so dass Ihre Definition der Vorlage p gültig ist.

p ist jedoch eine variable Vorlage, keine Variable; um eine Ist-Größe zu bekommen, müssen Sie es mit einem bestimmten Typ instanziiert, etwa so:

p<int> = func1; 
p<char> = func2; 
+1

In OPs Beispiel ist 'p' ein Typ, keine Variable. – SergeyA

+1

@SergeyA Ich bitte um Unterschiede. Wenn Sie mit C++ 14 kompilieren, ist 'p' eine variable Vorlage. – Brian

+0

@SergeyA OP scheint zu versuchen, eine Variable zu erstellen, die einen Zeiger entweder auf ein 'void (*) (int)' oder ein 'void (*) (void)' akzeptiert. – kfsone

0

In Ihrem Beispiel die Variable p ist in der Lage zugeordnete Objekte von nicht verwandten Arten sein (hier zwei unvereinbare Funktion Zeiger). Solch eine dynamische Änderung des offensichtlichen Typs wird nicht von Templates unterstützt, die streng statische (Kompilierzeit-) Konstrukte sind.

Wenn Sie ein solches sich verschiebendes Objekt erreichen möchten, müssen Typ löschen Techniken angewendet werden. In diesem speziellen Fall sieht std::function so aus, als könnte es Ihnen nützlich sein, aber Sie müssen sich immer noch für eine feste Funktionssignatur entscheiden (wie würden Sie das anders bezeichnen?).