【问题标题】:C++ template friend function not linkingC ++模板友元函数未链接
【发布时间】:2014-06-10 21:53:11
【问题描述】:

我有以下在 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 给我 LINK 错误:

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

如果我将代码放在 Text.h 中,它编译得很好。但我不想这样做,因为我想保持声明从实施中保持干净。我不明白为什么当函数在类外时链接器会在这种情况下抱怨?这是唯一的问题,而且类非常大,还有其他友元函数返回 CTextT。

【问题讨论】:

  • CTextT类模板的声明前添加template &lt;typename T&gt; class CTextT; template &lt;typename T&gt; CTextT&lt;T&gt; add(const CTextT&lt;T&gt;&amp; text1, const CTextT&lt;T&gt;&amp; text2);
  • @πάνταῥεῖ 仔细阅读后你是对的。道歉:(

标签: c++ visual-studio-2010 templates hyperlink friend


【解决方案1】:

当然它确实给出了链接器错误。您创建的add() 函数friend 不是函数模板!它是在类模板中声明的非模板函数。因此,您也无法将此函数定义为模板。你可以直接在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&);
    // ...
};

现在您提供的模板定义应该可以工作了。

【讨论】:

  • +1 导致我愚蠢的评论误导版主,道歉:(
  • friend CTextT&lt;T&gt; add(CTextT&lt;T&gt; const&amp;, CTextT&lt;T&gt; const&amp;); 应该是 friend CTextT&lt;T&gt; add&lt;&gt;(CTextT&lt;T&gt; const&amp;, CTextT&lt;T&gt; const&amp;); 或只是 friend CTextT add&lt;&gt;(const CTextT&amp;, const CTextT&amp;);
  • @Constructor:好点。我相应地更改了代码。谢谢!
  • 模板 - 在声明模板 朋友 CTextT add(CTextT const&, CTextT const&) 之前再次添加; -
【解决方案2】:

解决方法如下:

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 中,此代码将不再编译 - 将返回 INTERNAL COMPILER ERROR。

【讨论】:

    猜你喜欢
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 2011-07-15
    • 1970-01-01
    相关资源
    最近更新 更多