I have a class Vector<T>, and am using a library that provides a class YAML::Node. I would like to overload operator>> for these two types.
I have added the following declaration to Vector‘s declaration:
friend void operator>>(YAML::Node const & node, Vector<T> & v);
I have also added the following implementation of the function:
template<typename T>
void operator>>(YAML::Node const & node, Vector<T> & v) {
node[0] >> v.x;
node[1] >> v.y;
node[2] >> v.z;
}
Finally, I have added the following (attempt at) explicitly instantiating the template for T = num_t:
template
void operator>>(YAML::Node const & node, Vector<num_t> & v);
However, this results in the following linker error:
Error 9 error LNK2019: unresolved external symbol "void __cdecl operator>>(class YAML::Node const &,class Vector<double> &)" (??5@YAXAEBVNode@YAML@@AEAV?$Vector@N@@@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> >)" (?fromFile@Scene@@SA?AV1@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
(num_t is a typedef for double)
However, if I add the following (non-template) implementation of the function, everything compiles fine:
void operator>>(YAML::Node const & node, Vector<num_t> & v) {
node[0] >> v.x;
node[1] >> v.y;
node[2] >> v.z;
}
Why is the template version of the function not working?
Edit: Forgot to mention; the compiler is Visual Studio 11 Beta
Declaring the function as a
frienddoes not declare a function template; instead, each specialisation of the class template declares a non-template function, with its parameter types overloaded according to the template arguments. These will be chosen instead of the template you define; but they are not defined, hence the error.To fix it, you can either declare the function template before the class template (in which case the friend declaration will make that a friend, rather than declare a new function), or define the friend function inline, inside the class template, so that each specialisation of the class template defines the function as well as declaring it.