2017-03-27 2 views
0

Es scheint einfach zu sein, aber ich habe einige Schwierigkeiten mit der Syntax von std::enable_ifWie eine Klasse Mitglied funrtion für bestimmte Template-Typen deaktivieren

Die Situation ist eigentlich ganz einfach.

eine Template-Klasse mit Template-Parameter T

2 Funktionen, die für eine bestimmte Art von T werden sollen nicht umgesetzt.

Beide Funktionen haben keine Parameter oder Rückgabewerte von T

Eine Funktion eine int akzeptiert und die andere Funktion gibt einen int.

Jedes einfache Beispiel?

Oder gibt es eine andere Option (C++ 11), die std::enable_if nicht verwendet?

Antwort

1

Es ist wirklich einfach. Denken Sie daran, einen anderen Vorlagenparameter zu verwenden, der standardmäßig auf den Parameter class/struct template gesetzt ist.

Angenommen, Sie eine Klasse foo<T> mit zwei Mitgliedern wollen, void foo<T>::bar1 (int) und int foo<T>::bar2() und nehmen wir an, dass Sie möchten, dass bar1() und bar2() nur dann umgesetzt werden, wenn T von long unterscheidet.

können Sie tun, wie folgt

#include <type_traits> 

template <typename T> 
struct foo 
{ 
    template <typename U = T> 
    typename std::enable_if<false == std::is_same<U, long>::value>::type 
     bar1 (int) 
     { } 

    template <typename U = T> 
    typename std::enable_if<false == std::is_same<U, long>::value, int>::type 
     bar2() 
     { return 0; } 
}; 

int main() 
{ 
    foo<int> fi; 
    foo<long> fl; 

    fi.bar1(0); // compile 
    fi.bar2(); // compile 

    // fl.bar1(0); // compilation error 
    // fl.bar2(); // compilation error 
} 

Es besteht die Gefahr: jemand Ihre Kontrolle und explizit die U Typ umgehen kann als

foo<long> fl; 

fl.bar1<long long>(0); 

Um dieses Problem zu vermeiden, folgt, können Sie Ihre std::enable_if verbessern wie folgt testen

template <typename U = T> 
    typename std::enable_if 
     <sizeof(U) && (false == std::is_same<T, long>::value)>::type 
     bar1 (int) 
     { } 

    template <typename U = T> 
    typename std::enable_if 
     <sizeof(U) && (false == std::is_same<T, long>::value), int>::type 
     bar2() 
     { return 0; } 

Wenn Sie c ein verwenden, um eine C++ 14-Compiler, std::enable_if_t mit Ihnen ein paar typename und ein paar, wenn ::type zu vermeiden und den Code semplify wie folgt

template <typename U = T> 
    std::enable_if_t<sizeof(U) && (false == std::is_same<T, long>::value)> 
     bar1 (int) 
     { } 

    template <typename U = T> 
    std::enable_if_t<sizeof(U) && (false == std::is_same<T, long>::value), int> 
     bar2() 
     { return 0; } 
+1

Dank es perfekt tat whant ich wollte. Aber mir fehlt noch etwas Verständnis. Warum ist es nicht möglich, direkt 'T' anstelle von 'U' zu verwenden; ? Auch das 2. Beispiel sizeof (U) wie kann dies zu 0 führen? – Waldorf

Verwandte Themen