2017-07-07 2 views
0

Ich habe den folgenden Code:std :: enable_if auf std :: sagt is_convertible nicht herzuleiten Vorlage richtig

#include <iostream> 
#include <type_traits> 

template <typename T, typename std::enable_if 
           <std::is_convertible<int, T>::value, T>::type> 
void func(T a) 
{ 
    std::cout << a << std::endl; 
} 

template <typename T, typename std::enable_if 
           <!std::is_convertible<int, T>::value, T>::type> 
void func(T a) 
{ 
    a.print(); 
} 

class Test 
{ 
public: 
    void print() 
    { 
     std::cout << "Test" << std::endl; 
    } 
};  

int main() 
{ 
    func(3); 
    func("Test"); 
    return 0; 
} 

Mit diesem Code, ich den ersten Anruf zu func erwartet 3 auszudrucken (als int in der Tat ist konvertierbar zu int, die erste Spezialisierung sollte aufgerufen werden) und der zweite Aufruf an func zum Ausdrucken Test (Test() ist nicht umwandelbar zu int, so sollte die zweite Spezialisierung aufgerufen werden). Allerdings habe ich stattdessen einen Compiler-Fehler:

prog.cpp: In function ‘int main()’:

prog.cpp:27:8: error: no matching function for call to ‘func(int)’

prog.cpp:5:6: note: candidate: template [class T, typename std::enable_if[std::is_convertible[int, T>::value, T>::type > void func(T)

prog.cpp:5:6: note: template argument deduction/substitution failed:

prog.cpp:27:8: note: couldn't deduce template parameter ‘[anonymous>’

Wenn ich aber die Templat-Funktionen zu ändern, anstatt zu sein (während alles andere genau das gleiche zu verlassen):

template <typename T, typename std::enable_if 
           <std::is_convertible<int, T>::value, T>::type* = 
            nullptr> 
void func(T a) 
{ 
    std::cout << a << std::endl; 
} 

template <typename T, typename std::enable_if 
           <!std::is_convertible<int, T>::value, T>::type* = 
            nullptr> 
void func(T a) 
{ 
    a.print(); 
} 

dann alles kompiliert und Werke wie ich erwartet habe. Was macht diese zusätzliche Syntax und warum brauche ich sie?

+0

duplicate von [Wie funktioniert std :: enable \ _if arbeiten?] (Https://stackoverflow.com/questions/25284499/how-does-stdenable-if-work) –

Antwort

4
template<typename T, typename std::enable_if<std::is_convertible<int, T>::value, T>::type> 

, wenn wir das Rauschen zu entfernen, würde sich

template<typename T, typename Something<T>::type> 

, die als zweiten Parameter eine nicht-Typ-Parameter spezifiziert wird erklärt, die typename hier ist die verschachtelte type ist ein Name, der ein Art. Weitere Informationen finden Sie unter here.

Im ersten Fall ist der zweite Parameter kein Typ, daher passt der Funktionsaufruf func(3) nicht zu der Vorlage, die func<int, some_int>(3) erwartet.

+0

@ downvoter freundlicherweise erklären, ich bin fasziniert als warum dies als downvote würdig wahrgenommen wird –

+0

Sie haben die Frage nicht beantwortet. Ich habe in der Frage selbst angemerkt, dass die Bereitstellung eines Standardparameters von 'nullptr' das Problem löste - warum ist der Standardparameter erforderlich? –

+1

@R_Kapp Ich antwortete mit den ersten drei Sätzen. Alles unten wird hinzugefügt, weil ich annahm, dass Sie mit SFINAE nicht vertraut sind. –

Verwandte Themen