2017-09-11 19 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입니다.

::type이 다른 것으로 평가되도록 std::enable_if<std::is_integral<T_>::value,T_>을 상상해보십시오. 컴파일러는 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