2016-05-06 21 views
1

ich die solution here vereinfacht mir zu helfen, festzustellen, ob eine Klasse eine Memberfunktion hat:Vorlage SFINAE Innerhalb conditional_t ​​

template<typename T> 
struct HasTest{ 
    template<typename R, typename S = decltype(declval<R>().test())> static true_type Test(R*); 
    template<typename R> static false_type Test(...); 
    using def = decltype(Test<T>(0)); 
}; 

Ich brauche HasTest<T>::def::value in den Zustand eines conditional_t zu verwenden. Das Problem ist, dass ich dies mit einer ganzen Reihe von Funktionen tun muss, und da ich eine Struktur pro Funktion deklarieren muss, habe ich gehofft, einen Weg zu finden, die Substitution Fail Is Not An Error(SFINAE) innerhalb der Bedingung zu machen. Etwas wie:

conditional_t<struct { template<typename R, typename S = decltype(declval<R>().test())> static true_type Test(R*); template<typename R> static false_type Test(...); using def = decltype(Test<T>(0)); }::def, true_type, false_type> 

Dieses Beispiel kompiliert offenbar nicht, aber hoffentlich macht es, was ich versuche, klar zu machen.

Jetzt muss ich eine Struktur für jede Methode, die ich testen möchte in namespace details einrichten und dann in meiner conditional_t verwenden. Dies führt zu Verschmutzungen und trennt das Innenleben der SFINAE von der conditional_t, in der es verwendet wird.

Bietet C++ 14/17 mir eine alternative Möglichkeit, dies zu tun, oder gibt es eine Möglichkeit für mich zu deklarieren und zu verwenden eine anonyme struct in der conditional_t Zustand?

Ich habe einen einfachen Test erstellt here, dass Sie gerne Dinge ausprobieren können.

+2

Ich kann sofort sagen, dass anonyme Struktur dort nicht verwendet werden kann, da Vorlagenargumente externe Verknüpfung haben müssen. Nicht sicher, ob "anders" existiert. – SergeyA

+0

@SergeyA Ja, ich habe jede Problemumgehung ausprobiert, die mir einfällt: Ich kann kein Lambda aufrufen, ich kann keine Template-Spezialisierung lokal machen, ich frage hier als letzten Ausweg, weil mein nächster Stop darin besteht, alles im 'Namespace abzulegen Details' –

+0

@SergeyA C++ 11 entspannte die Regeln, externe Verknüpfung ist nicht mehr erforderlich. Aber Ihr Hauptpunkt besteht immer noch, es gibt immer noch Einschränkungen, die eine offensichtliche Antwort auf diese Frage verhindern. – hvd

Antwort

0

Nach dem Entwurf des Standard N4582§14.1/p2 Template-Parameter [temp.param](Hervorhebung von mir):

Eine Speicherklasse darf nicht in einem Template-Parameter Erklärung angegeben werden . In einer Template-Parameter Deklaration dürfen keine Typen definiert werden.

Folglich können Sie nicht so etwas wie:

conditional_t<bool, struct Foo {...}> 

Und ehrlich gesagt habe ich nicht einen guten Grund zu erlauben, solche Konstrukte in C++, noch mehr, wenn sie nicht namentlich Klassen finden (zB , denke an die Mangling-Probleme).