2014-06-24 11 views
7

Dank C++ 14, werden wir in Kürze in der Lage sein, ausführliche Trailing-Return-Typen einzuschränken; wie das allgemeine min Beispiel von David Abrahams 2011 post:SFINAE mit C++ 14 Rückgabetyp Abzug

template <typename T, typename U> 
auto min(T x, U y) 
    -> typename std::remove_reference< decltype(x < y ? x : y) >::type 
{ return x < y ? x : y; } 

unter 14 C++ der Rückgabetyp verzichtet werden kann, und min wie folgt geschrieben werden kann:

template <typename T, typename U> 
auto min(T x, U y) 
{ return x < y ? x : y; } 

Dies ist ein einfaches Beispiel Der Rückgabetypabzug ist jedoch sehr nützlich für generischen Code und kann viel Replikation vermeiden. Meine Frage ist, wie integrieren wir für solche Funktionen SFINAE-Techniken? Zum Beispiel, wie kann ich std::enable_if verwenden, um unsere min Funktion einzuschränken, um Typen zurückzugeben, die integral sind?

Antwort

12

Sie können die Funktion nicht mit dem Rückgabetyp SFINAE verwenden, wenn Sie Rückgabetypabzug verwenden. Dies ist in der

proposal erwähnt

Da der Rückgabetyp durch Instanziieren der Vorlage abgeleitet wird, wenn die Instantiierung ist schlecht ausgebildet ist, verursacht dies einen Fehler eher als eine Substitution Versagen.

Sie können jedoch einen zusätzlichen, nicht verwendeten Template-Parameter verwenden, um SFINAE auszuführen.

template <class T, class U> 
auto min1(T x, U y) 
{ return x < y ? x : y; } 

template <class T, class U, 
      class..., 
      class = std::enable_if_t<std::is_integral<T>::value && 
            std::is_integral<U>::value>> 
auto min2(T x, U y) 
{ 
    return x < y ? x : y; 
} 

struct foo {}; 

min1(foo{}, foo{}); // error - invalid operands to < 
min1(10, 20); 

min2(foo{}, foo{}); // error - no matching function min2 
min2(10, 20); 

Live demo

+2

+1 Sie sogar die 'std :: enable_if_t' Helfer Vorlage verwenden können. – 0x499602D2

+1

Ganz zu schweigen von 'std :: is_integal_v'. – chris

+1

@ 0x499602D2 [Sieht so aus] (http://coliru.stacked-crooked.com/a/8379c6d205210105) gcc-4.9's libstdC++ hat 'enable_if_it'. Ich werde es jetzt definitiv öfter benutzen. Mit gcc-4.8 habe ich es nie benutzt, weil ich die Kommandozeile von Coliru nicht zu sehr zwischen clang und gcc ändern wollte :) – Praetorian