2016-03-30 8 views
0

Der folgende Code wird beim Aufrufen der Memberfunktion A :: Get mit einem Stringliteral static_assert, vermutlich weil die Funktion, die Namensauflösung überlädt, die Vorlage unabhängig davon, ob sie ausgewählt ist, instanziiert.static_assert Triggerung während der Namensauflösung

template<typename T> 
struct helper 
{ 
    static_assert(std::is_integral<T>::value, "Must be integeral type"); 

    typedef T type; 
}; 

class A 
{ 
public: 
    A() 
    {} 

    std::string Get(const char* value) const 
    { 
     return std::string(value) + " (non-template)"; 
    } 

    template<typename T> 
    typename helper<T>::type Get(T value) const 
    { 
     return value; 
    } 
}; 

ich die Assertion durch Hinzufügen einer ‚Helfer‘ Spezialisierung stoppen kann, aber es gibt auch andere Situationen, in denen die Hilfsklasse verwendet wird, und es macht keinen Sinn für ‚const char *‘ in anderen Situationen zu spezialisieren machen .

Gibt es eine Möglichkeit, den helper :: type in diesem Fall mit 'const char *' zu instanziieren? Wenn nicht, was ist eine bessere Möglichkeit, die Hilfsklasse zu entwerfen, um dieses Problem zu vermeiden?

+0

Sie können [std :: enable_if] (http://en.cppreference.com/w/cpp/types/enable_if) überprüfen – Mine

Antwort

0

Wenn Sie nur die gestaffelte Get-Methode stoppen möchten, die mit const char* instanziiert wird, können Sie std::enable_if verwenden. Auf diese Weise können Sie die Funktion deaktivieren, wenn T vom Typ const char* ist. Hier ist eine Implementierung Ihrer Get Methode std::enable_if:

template<typename T> 
typename helper<typename std::enable_if<!std::is_same<const char*, T>::value>::type>::type Get(T value) const 
{ 
    return value; 
} 

Es ziemlich lang, aber es vermeidet helper<T> für den const char* Fall zu spezialisieren. Es funktioniert, indem die Methode von der Überladungsauflösung entfernt wird, wenn T ist.

Sie können die Dokumentation für std::is_samehere sehen. Beide Typen sind im Header <type_traits.

Verwandte Themen