C ++ erkennt das Vorhandensein freier Funktionen mit expliziten Parametern

8

Ich schreibe einige Typeigenschaften, um zu sehen, ob eine freie Funktion mit einer bestimmten Menge von Parametern existiert. Die Funktionen haben eine Signatur, die ungefähr so ​​aussieht:

%Vor%

Ich kenne im Voraus die Werte für T , SomeClass und SomeType . Ich möchte, dass die Eigenschaft true zurückgibt, wenn diese Funktion mit genau diesen Parametern existiert und keine implizite Konvertierung verwendet wird.

Ich kann leicht Code schreiben, um zu erkennen, ob diese Funktion existiert, indem SFINAE verwendet wird, um zu versuchen, sie aufzurufen, z. B.

%Vor%

und Testen der Rückgabetypen dieser Funktionen. Da ich SomeClass ( Y ) an die Funktion übergeben kann, kann ADL den Compiler in die entsprechenden Namespaces schauen lassen, damit er nicht von der Dummy-Version von func , die ich für die Tests definiert habe, verwirrt wird.

Das Problem, auf das ich hier gestoßen bin, ist, dass, da das SomeType ( Z im obigen Test) durch eine konstante Referenz übergeben wird, es implizit in andere Typen konvertiert werden kann. Zum Beispiel könnte jemand eine Funktion definieren wie: template <class T> void func( SomeClass &, double const & ); und für jeden arithmetischen Typ für Z wird mein Test bestehen. Ich möchte es nur passieren, wenn Z der wahre Typ ist, in diesem Fall ein double .

Ich habe versucht, dies zu lösen, indem ich Funktionszeiger in einem Schema wie dem folgenden verwende:

%Vor%

Theoretisch würde das großartig funktionieren, aber das Problem, auf das ich gestoßen bin, ist, dass eine später definierte Benutzerversion von func vom Test nicht gesehen wird - es sieht nur den Dummy func , den ich für den Compiler definieren muss glücklich sein. Leider kann ich den Typ SomeClass hier nicht übergeben, also kann ADL nicht eingreifen, um &func<X> zu bekommen, um später definierte Benutzerfunktionen nachzuschlagen.

Gibt es eine Möglichkeit, das zu erreichen? Die Lösung muss keine Funktionszeiger verwenden, es muss nur ein Merkmal sein, das true zurückgibt, wenn eine freie Funktion mit genau einem bereitgestellten Satz von Parametern existiert.

Als Referenz für das gewünschte Verhalten:

%Vor%     
Azoth 17.03.2014, 20:05
quelle

1 Antwort

7

Ich konnte dies mithilfe der folgenden Technik lösen, dank der Hilfe von dyp:

Diese Lösung verwendet keine Funktionszeiger mehr und stützt sich stattdessen auf eine Proxy-Klasse, die eine implizite Konvertierung verhindert:

%Vor%

was wie folgt verwendet werden kann:

%Vor%

Wenn Sie mit den Konvertierungsoperatoren innerhalb von NoConvert spielen, können Sie dies mit der Übergabe nach Wert, Referenz oder konstanter Referenz durchführen.

Wenn beispielsweise in der aktuellen Verwendung der Konvertierungsoperator für NoConvert<std::string> durch einen Wertparameter von std::string ausgelöst wird, sind beide Überladungen gültig, und somit gibt es eine Mehrdeutigkeit, was bedeutet, dass SFINAE dies ausfiltert und co_de% Test zum Bestehen. Im Falle eines konstanten Referenzparameters hat die Überladung mit konstantem Referenzwert Vorrang und erlaubt die Überschreitung der std::false_type Testüberlastung ordnungsgemäß.

Diese Lösung basiert auch auf der Fähigkeit, ADL zu verwenden, um den Namen der Funktion aufzulösen, was mit dem Funktionszeiger-Ansatz nicht möglich war.

    
Azoth 17.03.2014, 22:36
quelle