2017-09-11 8 views
7

次の例を考えてみましょう。テンプレートタイプの控除が失敗しますか?

#include <type_traits> 
#include <iostream> 
using namespace std; 

template <typename T_> 
using Integral = typename std::enable_if<std::is_integral<T_>::value,T_>::type; 
template <typename T_> 
using NotIntegral = typename std::enable_if<!std::is_integral<T_>::value, T_>::type; 

template <typename T_> 
void printIt(const Integral<T_> &value) { cout << "Integral == " << value << endl; } 

template <typename T_> 
void printIt(const NotIntegral<T_> &value) { cout << "Non Integral == " << value << endl; } 

template <typename T_> 
void foo(const T_ &value) { printIt<T_>(value); } 

int main(int argc, char** argv) 
{ 
    printIt<int>(66); //Must explicitly provide argument type. 
    //printIt(33);  //Compiler error. No overloaded function....???? 
    foo(29.); 

    return 0; 
} 

なぜテンプレートパラメータのタイプを明示的に設定する必要がありますか?コンパイラはint型の引数であると判断する必要がありますか?

答えて

11

なぜテンプレートパラメータのタイプを明示的に設定する必要がありますか?

これはnon-deduced contextsであるためです。

std::enable_if<std::is_integral<T_>::value,T_>を具体的に想像して、::typeが他と評価しているとします。コンパイラはtypename something<T>::typeからTへのマッピングを認識できません。非マッチングのオーバーロードが出SFINAEdされるように

あなたは、戻り値の型の一部としてstd::enable_ifを配置することにより、ご希望の結果を得ることができます。

template <typename T> 
auto printIt(T x) -> std::enable_if_t<std::is_integral_v<T>, void> { /*...*/ } 

template <typename T> 
auto printIt(T x) -> std::enable_if_t<!std::is_integral_v<T>, void> { /*...*/ } 

live wandbox example

関連する問題