2017-07-07 57 views
0

我有以下代碼:的std :: enable_if前提上的std :: is_convertible不推導模板正確

#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; 
} 

有了這個代碼,我預計func第一次調用打印出來3(如int的確可轉換爲int,應該叫第一個專業化),第二個要求func打印出TestTest()不可轉換爲int,所以應該調用第二個專業化)。但是,我反而得到一個編譯錯誤:

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>’

但是,如果我改變了模板的功能,而不是爲(同時保留一切完全一樣):

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(); 
} 

那麼一切編譯和作品如我所料。這是什麼額外的語法,爲什麼我需要它?

+0

重複[如何std :: enable \ _if工作?](https://stackoverflow.com/questions/25284499/how-does-stdenable-if-work) –

回答

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

如果我們以去除噪聲,將成爲

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

其被聲明作爲其第二個參數的非類型參數,這裏的typename被指定嵌套type是的一個名類型。有關更多信息,請參閱here

在第一種情況下,第二個參數是非類型的,所以函數調用func(3)不適合期待func<int, some_int>(3)的模板。

+0

@downvoter好心解釋,我很感興趣爲什麼這被視爲downvote值得 –

+0

你還沒有回答這個問題。我在問題本身中指出,提供'nullptr'的默認參數解決了問題 - 爲什麼需要默認參數? –

+1

@R_Kapp我回答了前三句話。下面的所有內容都被添加了,因爲我認爲你對SFINAE並不熟悉。 –

相關問題