2012-03-08 3 views
1

클래스가 Vector<T>이고 클래스가 YAML::Node 인 라이브러리를 사용하고 있습니다. 이 두 가지 유형에 대해 operator>>을 오버로드하고 싶습니다.연산자의 명시 적 인스턴스화 >> overload

내가 Vector의 선언에 다음과 같은 선언을 추가 한이 : 마지막으로, 나는 다음과 같은 (시도를 추가 한

template<typename T> 
void operator>>(YAML::Node const & node, Vector<T> & v) { 
    node[0] >> v.x; 
    node[1] >> v.y; 
    node[2] >> v.z; 
} 

:

friend void operator>>(YAML::Node const & node, Vector<T> & v); 

는 또한 함수의 다음 구현을 추가 한 at) 템플릿을 명시 적으로 인스턴스화하여 T = num_t :

template 
void operator>>(YAML::Node const & node, Vector<num_t> & v); 

그러나, 이것은 다음과 같은 링커 오류가 발생합니다

Error 9 error LNK2019: unresolved external symbol "void __cdecl operator>>(class YAML::Node const &,class Vector<double> &)" ([email protected]@[email protected]@[email protected]@@@Z) referenced in function "public: static class Scene __cdecl Scene::fromFile(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" ([email protected]@@[email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@Z) 

,

그러나 나는이 기능의 구현을 다음 (템플릿이 아닌)을 추가하면, 모든 것을 컴파일 (num_tdouble에 대한 형식 정의입니다) 세부 사항 :

void operator>>(YAML::Node const & node, Vector<num_t> & v) { 
    node[0] >> v.x; 
    node[1] >> v.y; 
    node[2] >> v.z; 
} 

왜 함수의 템플릿 버전이 작동하지 않습니까?

편집 : 언급하는 것을 잊었습니다; 컴파일러는 Visual Studio 11입니다.

답변

3

friend으로 함수를 선언하면 이 아닌은 함수 템플릿을 선언합니다. 대신 클래스 템플릿의 각 특수화는 템플릿 인수에 따라 오버로드 된 매개 변수 유형을 사용하여 비 템플릿 함수를 선언합니다. 이 템플릿은 정의한 템플릿 대신 선택됩니다. 그러나 그것들은 정의되지 않았다. 그러므로 오류이다.

수정하려면 클래스 템플릿 앞에 함수 템플릿을 선언하거나 (이 경우 친구 선언을 통해 새 함수를 선언하는 대신 친구로 만들 수 있음) 또는 클래스 내부에서 친구 함수를 인라인으로 정의 할 수 있습니다 템플리트를 사용하여 클래스 템플리트의 각 특수화가 함수를 정의하고 선언 할 수 있도록합니다.

+0

감사합니다. –

0

이상합니다. 나는 틀린 것을 볼 수 없으며, 심지어 MSDN 문서 (Visual C++의 권리?)도 템플릿 인스턴스화가 템플릿 인수를 추론해야 함을 확인합니다. 인스턴스화 일치의 인수 과부하가 걸린 운영자의 경우 고장 났을 수 있습니까?

명백한 템플릿 인수를 추가해도 괜찮습니다.

또한 typedef로 혼란스러워하고 있을까요? 너는 결코 알지 못한다! double을 사용해보십시오.

2

글쎄, 문제는 당신이 선언 한 friend이 템플릿 연산자가 아니며 시프트 연산자를 사용하지 않아도된다는 것입니다. 사실, 템플릿은 컴파일러가 불평해야하는 private 멤버를 사용합니다.

template <typename T> 
class foo 
{ 
public: 
    template <typename S> 
    friend void f(foo<S>); 

private: 
    T value; 
}; 

template <typename T> 
void f(foo<T> v) 
{ 
    v.value; 
} 
template void f(foo<int>); 

int main() 
{ 
    foo<int> v; 
    f(v); 
} 

이 코드 중 하나를 연결하지 않습니다

friend void f(foo<T>); 

하여 친구 선언을 교체하고 실제로 기능을 나타내는 컴파일 타임 오류가 발생합니다 경우 다음과 같이이 모양 방법 예입니다 f() 님은 친구가 아닙니다.