Weird Substitution fehlgeschlagen mit C ++ 11 variadic Vorlage

8

Es fällt mir schwer herauszufinden, was den Ersatzfehler in diesem Beispielcode verursacht:

%Vor%

Irgendwo in main:

%Vor%

Der Compiler sagt:

%Vor%

Was mich verwirrt ist, dass call1 funktioniert, während call2 nicht funktioniert. Irgendwelche Tipps? =)

    
user3026691 24.11.2013, 07:21
quelle

3 Antworten

3

Erstens: Sie können weniger Argumente angeben als Sie verwenden und den Compiler den Rest ableiten lassen:

%Vor%

Dies bedeutet, dass Params noch offen ist, um beim Aufruf zusätzliche Typen hinzuzufügen. Aber wenn Sie die Funktionsadresse nehmen, wird sie definiert und geschlossen:

%Vor%

Wenn Sie Ihre Funktion call1 direkt aufrufen:

%Vor%

Der Compiler kann folgern, dass Sie genau 3 Ints haben, weil Sie ihm gerade 3 Ints geschickt haben. Auf diese Weise muss der letzte Parameter std::function<bool(int, int, int)> sein, weil wir vollständig abgeleitet haben, was Params... bedeutet, und es gibt keinen Platz für mehr Typen.

Jetzt der problematische Fall:

%Vor%

Hier haben Sie dem Compiler mitgeteilt, dass die ersten 3 Elemente von Params alle Ints sind. %Code%. Beachten Sie, dass es noch offen ist, etwas anderes hinzuzufügen, wenn der Abzug dies sagt. Ersetzen wir haben: Params = {int, int, int, ...} . Der Compiler kann unmöglich wissen, was dieser unvollständige Typ bedeutet, es sei denn, Sie übergeben explizit eine std::function<bool(int, int, int, ...)> func (exakte Übereinstimmung). Es weiß noch nicht, dass es einen Konstruktor haben kann, der den Funktionszeiger nimmt, den Sie zur Verfügung gestellt haben, also gibt es eine Nichtübereinstimmung. Nun hat der Compiler nicht genug Daten, um zu entscheiden, ob er mehr Typen in std:function benötigt oder nicht. Fehler.

Aber beachte diesen interessanten Fall:

%Vor%

Hier erzwingen Sie, dass Params vollständig ist. Es gibt keinen Abzug zu bewerten. Obwohl hässlich, funktioniert das auch:

%Vor%     
Guilherme Bernal 24.11.2013, 13:02
quelle
1

Der Compiler kann den Typ mit Ihrem aktuellen Code nicht ableiten (obwohl der Funktionszeiger implizit in ein std::function konvertiert werden kann). Sie könnten eine Merkmalsklasse erstellen, um den richtigen Typ abzuleiten.

%Vor%     
Snps 24.11.2013 13:02
quelle
0

Der Typ des Ausdrucks f ist ein Zeiger auf die Funktion, d.h. bool (*)(int, int, float) . Die explizite Instanziierung von call2 template hat jedoch den Typ void foo (std::function<bool (int, int, float)> ) , d. H. Der Parametertyp ist anders, daher die Nichtübereinstimmung.

Workaround:

%Vor%

Ausnutzung der Möglichkeit, ein std::function von einem Funktionszeiger zu konstruieren.

    
chill 24.11.2013 12:27
quelle

Tags und Links