C++模板朋友函数未链接

C++ template friend function not linking

本文关键字:链接 函数 朋友 C++      更新时间:2023-10-16

我有以下代码在VC6中编译:

文本.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);}
    }
    ....................
};

在标题的末尾

 #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 ;
}

但VC2010给我链接错误:

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>.DebugUnitTestText.exe : fatal error LNK1120: 1 unresolved externals

如果我把代码放在Text.h中,它编译得很好。但我不想这样做,因为我想保持声明不被执行。我不明白为什么链接器在这种情况下抱怨函数在类之外?这是唯一的问题,并且类很大,还有其他返回CTextT的友元函数。

当然,它确实给出了一个链接器错误。您制作的friendadd()函数不是函数模板!它是在类模板中声明的非模板函数。因此,您也无法将此函数定义为模板。您可以在friend声明中直接定义它。

另一种选择是在类模板之前声明函数模板。当然,这也需要类模板的声明。以下内容应该有效:

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&);
    // ...
};

现在,您给出的模板定义应该可以工作了。

解决方案如下:

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 ;
}

我发现以下MSDN链接解释了如何在模板中添加好友函数-http://msdn.microsoft.com/en-us/library/f1b2td24.aspx.

我进行了测试,它适用于VS2010和VS2012。VC6不需要第二个模板声明(它从类中获取(,并且在VC6中,此代码将不再编译-将返回内部编译器错误。