2015-12-19 53 views
6

所以,我下面的代碼的某個地方本網頁上設置的例子: http://eli.thegreenplace.net/2014/sfinae-and-enable_if/SFINAE:性病:: enable_if作爲函數參數

這是我有:

template<typename T> 
void fun(const typename std::enable_if_t<std::is_integral<T>::value, T>& val) { 
    std::cout << "fun<int>"; 
} 

template<typename T> 
void fun(const typename std::enable_if_t<std::is_floating_point<T>::value, T>& val) { 
    std::cout << "fun<float>"; 
} 

int main() 
{ 
    fun(4); 
    fun(4.4); 
} 

這樣我將不得不寫:

fun<int>(4); 
fun<double>(4.4); 

我會如何避免這種情況?

編譯器抱怨說它不能推導出參數T

回答

5

這些例子是錯誤的,因爲Tnon-deduced context。除非您調用fun<int>(4);這樣的函數,否則代碼將無法編譯,但這可能不是作者想要顯示的內容。

正確的用法是允許編譯器推導出T,並在其他地方放置SFINAE條件,例如,在返回類型的語法:

template <typename T> 
auto fun(const T& val) 
    -> typename std::enable_if<std::is_integral<T>::value>::type 
{ 
    std::cout << "fun<int>"; 
} 

template <typename T> 
auto fun(const T& val) 
    -> typename std::enable_if<std::is_floating_point<T>::value>::type 
{ 
    std::cout << "fun<float>"; 
} 

DEMO

此外,typename在你的代碼違背了你的std::enable_if_t使用。

二者必選其一(C++ 11):

typename std::enable_if<...>::type 

或(C++ 14):

std::enable_if_t<...> 

將如何在沒有按一個構造函數,工作雖然沒有返回類型?

在構造函數的情況下,SFINAE條件可以隱藏在一個模板參數列表:

struct A 
{  
    template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0> 
    A(const T& val) 
    { 
     std::cout << "A<int>"; 
    } 

    template <typename T, typename std::enable_if<std::is_floating_point<T>::value, int>::type = 0> 
    A(const T& val) 
    { 
     std::cout << "A<float>"; 
    } 
}; 

DEMO 2

+0

我明白了。如何在沒有返回類型的構造函數中工作? – DeiDei

+0

@DeiDei查看更新 –

+0

使用'int'作爲'std :: enable_if'的第二個參數有什麼意義?它是任意的嗎?還是因爲'int = 0'是安全的? – Jacob

1

要允許扣除你需要的是直截了當基於T函數參數。然後你需要找出把enable_if放在哪裏(確實不允許推導出T)。常用選項位於返回類型或您忽略的額外默認參數上。

這裏有一些很好的例子:http://en.cppreference.com/w/cpp/types/enable_if