Wie kann ich den C ++ - Compiler veranlassen, T indirekt abzuleiten?

8

Mein Template-Fu ist ziemlich schwach. Ich habe diesen Code:

%Vor%

... aber ich möchte etwas, das lesbarer ist als Cs fiese Funktion Pointer-Syntax von void(*func)(T*) .

Jemand in meinem Team hat dies vorgeschlagen:

%Vor%

(Ich diskutiere immer noch, ob das tatsächlich lesbarer ist, aber das ist ein separates Problem.)

Wie kann ich dem Compiler helfen herauszufinden, was T ist, ohne es explizit im Aufrufer angeben zu müssen?

    
scobi 19.12.2014, 12:40
quelle

3 Antworten

9

Sie können T aus dem Funktionstyp mithilfe einer Merkmalsklasse extrahieren.

%Vor%

Ihr Beispiel kann wie folgt geändert werden:

%Vor%

Diese Technik wird in der Boost-Typ-Traits-Bibliothek verwendet: Ссылка

Dieser Blogeintrag geht ein bisschen genauer auf die Implementierung der Technik ein: Ссылка

Leider verbirgt dieser Ansatz die Informationen in der Signatur von Foo über die Einschränkungen des übergebenen Arguments. Im obigen Beispiel muss das Argument eine Funktion vom Typ void(T*) sein.

Diese alternative Syntax macht das gleiche wie das ursprüngliche Beispiel und ist etwas besser lesbar:

%Vor%

Eine andere alternative Syntax, die besser lesbar ist, kann mit den Alias-Vorlagen von C ++ 11 wie folgt erreicht werden:

%Vor%

Leider kompiliert die neueste MSVC das nicht und meldet einen internen Compilerfehler.

    
willj 19.12.2014, 12:57
quelle
1

Sie können den Typ basierend auf einem verschachtelten Namen nicht ableiten: Es gibt keinen Grund, warum verschiedene Instanziierungen des äußeren Typs keinen identischen inneren Typ definieren. Sie könnten jedoch einen using Alias ​​verwenden:

%Vor%

Persönlich würde ich jedoch davon abraten, eines davon zu verwenden: In der Praxis erscheint es viel sinnvoller, ein Funktionsobjekt zu verwenden, das es später ermöglicht, ein Objekt mit geeigneten Funktionsaufrufoperatoren zu verwenden. Bei Callbacks ist es üblich, dass Sie Hilfsdaten eingeben müssen. Das heißt, Sie würden entweder eine unbeschränkte Vorlage verwenden oder eine, die einen Typ gelöscht hat, abhängig davon, was genau Sie tun möchten:

%Vor%

Die unbeschränkte Version hat den Vorteil, dass sie den Funktionsaufruf potenziell inline machen kann, aber sie hat den Nachteil, dass jeder Funktionsobjekttyp eine neue Instanziierung erzeugt und dass die Argumenttypen wahrscheinlich variieren. Die Typ-gelöschte Version muss tatsächlich so etwas wie einen virtuellen Funktionsaufruf machen, aber es gibt nur eine Instanz der Funktionsvorlage (pro Argumenttyp T , natürlich).

Der Typ der gelöschten Version wird zwar nicht von einem Funktionszeiger (oder irgendeinem anderen Argument, das kein std::function<void(X*)> ist) abgeleitet, d. h., Sie möchten möglicherweise eine Weiterleitungsfunktion haben

%Vor%     
Dietmar Kühl 19.12.2014 14:10
quelle
0

In C ++ 98 und C ++ 03 funktioniert die Template-Argumentableitung nur mit Funktionen (und Methoden).

Ich glaube nicht, dass sich das Bild in den neueren Standards geändert hat.

    
bltxd 19.12.2014 12:43
quelle

Tags und Links