Ich mache eine Art Wrapper, der so aussieht:
%Vor%Und ich bekomme diesen Fehler:
Apply
: keine übereinstimmende überladene Funktion gefunden. void Apply(void (__thiscall T::* )(Value),T *,Value)
: Vorlagenparameter Value
ist mehrdeutig, könnte int
oder const int &
sein. void Apply(void (__thiscall T::* )(Value),T *,Value)
: konnte das Template-Argument für Value
von const int
nicht ableiten. Also ich verstehe, dass es aus der Template-Parameterableitung kommt, aber ich verstehe nicht, wie. Warum würde Value
nicht beide Male const int&
auswerten?
Momentan wird der Template-Parameter Value
an zwei verschiedenen Stellen im Aufruf von Apply
abgeleitet: vom Zeiger zum Elementfunktionsargument und vom letzten Argument. Von &Foo::MyFunc
, Value
wird als int const&
abgeleitet. Von f.GetValue()
, Value
wird als int
abgeleitet. Dies liegt daran, dass Referenz- und Top-Level-CV-Qualifikationsmerkmale für den Vorlagenabzug gelöscht werden. Da diese beiden Abzüge für den Parameter Value
unterschiedlich sind, schlägt der Abzug fehl - wodurch Apply()
aus der Überladungsmenge entfernt wird, und infolgedessen haben wir keine brauchbare Überladung.
Das Problem ist, dass Value
an zwei verschiedenen Stellen abgeleitet wird, also verhindern wir das. Eine Möglichkeit besteht darin, eine der Verwendungen in einen nicht abgeleiteten Kontext zu verpacken:
Das letzte Argument, v
, hat den Typ non_deduced_t<Value>
, was, wie der Name schon sagt, ein nicht-hergeleiteter Kontext ist. Also wird Value
während des Template-Deduktionsprozesses als int const&
vom Zeiger auf die Member-Funktion abgeleitet (wie zuvor) und jetzt stecken wir das einfach in den Typ für v
.
Alternativ können Sie cb
als eigenen Vorlagenparameter ableiten. An diesem Punkt wird Apply()
nur auf std::invoke()
reduziert.
Der Ausdruck f.GetValue()
ist ein Lvalue vom Typ const int
. Wenn dieser Wert übergeben wird, leitet der Argumentabzug des Templates den Typ int
ab. Im Allgemeinen führt die Ableitung von Value
von Value v
zu nie zu einer Referenz oder einem Typ mit der höchsten cv-Qualifikation.
Sie werden wahrscheinlich zwei separate Template-Parameter anstelle von Value
haben (eine für das Argument des Funktionstyps, eine für den eigentlichen Argumenttyp) und SFINAE verwenden, um Apply
zu deaktivieren, wenn cb
nicht ist aufrufbar mit v
(oder static_assert
für einen schweren Fehler).
Tags und Links c++ templates ambiguous-call ambiguous template-deduction