2017-04-24 82 views
3
#include <limits> 
    #include <iostream> 
    using std::cerr; 

    template< typename T > 
    int get_max_if_integral() 
     { 
     if (std::is_integral<T>::value) return (int) std::numeric_limits<T>::max(); 
     else return 0; 
     } 

struct S {}; 

int main() 
    { 
    cerr<<"int: "<<get_max_if_integral<int>()<<"\n"; 
    cerr<<"short: "<<get_max_if_integral<short>()<<"\n"; 
    cerr<<"float: "<<get_max_if_integral<float>()<<"\n"; 
// cerr<<"S: "<<get_max_if_integral<S>()<<"\n"; 
    } 

這將返回所需的結果實例...修復編譯錯誤時模板用非標量型

int: 2147483647 
short: 32767 
float: 0 

但是,如果我去掉最後一行,我得到:

x.cpp: In instantiation of ‘int get_max_if_integral() [with T = S]’: 
x.cpp:22:40: required from here 
x.cpp:11:82: error: invalid cast from type ‘S’ to type ‘int’ 
     if (std::is_integral<T>::value) return (int) std::numeric_limits<T>::max(); 

在這種情況下,我希望函數返回0

+3

[constexpr如果(https://wandbox.org/permlink/qEJmMJgkvpkzF3Zm)將做的工作,但是這是C + +17。 – xinaiz

+0

@BlackMoses:太棒了! – nobar

+1

澄清,因爲答案沒有解釋:錯誤是由於使用常規的'if',[兩個分支對編譯器可見](http://ideone.com/zQTmqu);因爲'T'是'S'時''(int)std :: numeric_limits :: max()'無效,編譯器會抱怨,即使它永遠不會被執行。使用SFINAE,每個分支都是一個獨特的功能。如果使用constexpr,在編譯之前會拋棄'false'分支,從而使其像內聯SFINAE一樣工作。 –

回答

4

我建議你在兩個不同的功能劃分的功能,SFINAE啓用

template <typename T> 
typename std::enable_if<true == std::is_integral<T>::value, int>::type 
    get_max_if_integral() 
{ return (int) std::numeric_limits<T>::max(); } 

template <typename T> 
typename std::enable_if<false == std::is_integral<T>::value, int>::type 
    get_max_if_integral() 
{ return 0; }