2014-05-25 7 views
4

템플릿 인수 형식이 동일한 경우 두 개의 템플릿 인수 함수를 특수화하려고합니다. 나는 그에게 다음과 같은 방법으로 수행템플릿 함수 특수화 : 링커 오류

#include <iostream> 
#include <type_traits> 

using namespace std; 

template<typename U, typename T> 
int fun(U& u, T t); 

template<> 
inline 
int fun(int& u, float t) 
{ 
    cout << "int, float" << endl; 
    return 0; 
} 

template<typename U, typename T> 
inline 
int fun(U& u, typename std::enable_if<std::is_same<U, T>::value ,T>::type t) 
{ 
    cout << "U == T" << endl; 
    return 0; 
} 

int main() 
{ 
    int a; 
    float b1, b2; 

    fun(a, b1); 
    fun(b1, b2); 

    return 0; 
} 

이 코드는 잘 컴파일 (GCC 4.8.2)하지만, 링커는 UT가 동일한 유형의 모든 fun 호출에 정의되지 않은 refernces을 제공합니다. 왜 작동하지 않습니까?


링커 출력 :

g++ -std=c++11 test.cpp 

/tmp/cc7HWboz.o: In function `main': 
test.cpp:(.text+0x66): undefined reference to `int fun<float, float>(float&, float)' 
collect2: error: ld returned 1 exit status 
+0

'T'와 'U'가 다른 경우 링커 오류가 없습니까? –

+0

@KerrekSB 정답, 구체적인 예를 들어 편집 된 게시물 참조 – user2052436

답변

5

인한 문제

다른 funstd::enable_if을 사용하여 instatiation을 두 가지 유형으로 보호하는 데 큰 문제가 있습니다. 암시 적으로 유형 T을 추론 할 수 없습니다.

b1funb2를 호출 할 때 따라서 ... 당신이 정의를 가지고하지 않은 template<typename U, typename T> int fun(U& u, T t)을 인스턴스화하는 링커 오류를 매개 변수로 있다는 것을 의미한다.


솔루션

아래 작성된 코드에 많은 대안이있다, 그러나 나는이 혼란을 취소 할 수 생각한다. 컴파일러 위의 우리의 템플릿에 모두 TU을 추론 할 수에서

template< 
    typename U, 
    typename T, 
    typename = typename std::enable_if<std::is_same<U, T>::value>::type 
> 
inline int fun(U& u, T t) 
{ 
    cout << "U == T" << endl; 
    return 0; 
} 

inline int fun(int& u, float t) 
{ 
    cout << "int, float" << endl; 
    return 0; 
} 

도했다 템플릿의 명시 적 전문성에 대한 필요가 없습니다; 우리는 오버로드를위한 C++의 규칙을 사용할 수 있고 int&, floatU&, T을 추론하는 것보다 더 좋은 일치 일 때 컴파일러가 결정하도록 할 수 있습니다.

+1

감사. 'fun (b1, b2)'를 시도해 보았지만 제대로 작동합니다. – user2052436