问题
I have the following code which compiles in VC6 :
Text.h:
template <typename T>
class CTextT
{
public:
friend CTextT add(const CTextT& text1, const CTextT& text2) ;
friend CTextT operator+(const CTextT& string1, const CTextT& string2)
{
return ::add(string1, string2);}
}
....................
};
And at the end of the header
#include "Text.inl"
Text.inl:
template <typename T>
CTextT<T> add(const CTextT<T>& text1, const CTextT<T>& text2)
{
CTextT<T> temp ;
// do something
return temp ;
}
But VC2010 gives me LINK error:
error LNK2019: unresolved external symbol "class CTextT<char> __cdecl add(class CTextT<char> const &,class CTextT<char> const &)" (?add@@YA?AV?$CTextT@D@@ABV1@0@Z)
referenced in function "class CTextT<char> __cdecl operator+(class CTextT<char> const &,class CTextT<char> const &)" (??H@YA?AV?$CTextT@D@@ABV0@0@Z)
1>.\Debug\UnitTestText.exe : fatal error LNK1120: 1 unresolved externals
If I place the code in the Text.h it compiles fine. But I do not want to do this because I want to keep declaration clean from implementation. I can't figure why linker is complaining in this case when the function is outside the class? This is the only problem and the class is very big and there are other friend functions returning CTextT.
回答1:
Of course it does give a linker error. The add()
function you made a friend
isn't a function template! It is a non-template function declared inside a class template. As a result, you won't be able to define this function as a template, either. You can directly define it at the friend
declaration.
The alternative is to declare the function template prior to the class template. Of course, this requires a declaration of the class template, too. The following should work:
template <typename T> class CTextT;
template <typename T> CTextT<T> add(CTextT<T> const&, CTextT<T> const&);
template <typename T>
class CTextT
{
friend CTextT<T> add<>(CTextT<T> const&, CTextT<T> const&);
// ...
};
Now the template definition you have give should work.
回答2:
The solution is following:
template <typename T>
class CTextT
{
public:
template <typename T>
friend CTextT<T> add(CTextT<T> const&, CTextT<T> const&) ;
friend CTextT<T> operator+(const CTextT<T>& string1, const CTextT<T>& string2)
{ return ::add(string1, string2); }
};
template <typename T>
CTextT<T> add(CTextT<T> const&, CTextT<T> const&)
{
CTextT<T> temp ;
return temp ;
}
I found the following link to MSDN explaining how to add friend functions in templates - http://msdn.microsoft.com/en-us/library/f1b2td24.aspx.
I tested and it works for VS2010 and VS2012. VC6 does not need the second template declaration (it takes it from the class) and in VC6 this code will not compile anymore - will return INTERNAL COMPILER ERROR.
来源:https://stackoverflow.com/questions/24151473/c-template-friend-function-not-linking