LNK2019 - 为什么未解析外部模板友好功能

时间:2014-01-15 16:29:55

标签: c++ templates linker

我没有收到此错误:

#include <iostream>
using namespace std;

// LNK2019f.cpp
// LNK2019 expected
template<class T>
void f(T) {}

template<class T>
struct S {
   friend void f(T);
   // try the folowing line instead
   // friend void f<T>(T);
};

int main() {
   S<int> s;
   int a = 2;
   f(a);   // unresolved external
}

取自http://msdn.microsoft.com/en-us/library/799kze2z(v=vs.80).aspx

如果我注释掉 S&lt; <错误>,为什么错误不会显示? int&gt; s ?我得到了我还需要声明模板参数列表,但我没有看到该模板化结构与 f(a)调用之间的联系..

另一个奇怪的事情:如果我只注释 f(a)调用(我将所有其余部分保留在原地),它会再次编译。我正在使用MSVC2012。

2 个答案:

答案 0 :(得分:2)

发生错误是因为您的朋友声明充当另一个非模板化f函数的函数声明。

你必须这样声明它才能告诉编译器它是一个模板函数:

    friend void f<T>(T);

考虑以下示例:

template<class T>
struct S {
    friend void foo(int);
};

int main() {
    S<int> s;
    foo(42);
}

这将抛出一个链接器错误,在此处对未解析的外部符号foo进行嘀咕。在这种情况下,foo已声明但未通过好友声明定义。

如果我们现在注释掉S<int> s;,我们现在得到的不是链接器而是编译器错误:'foo': identifier not found,因为foo尚未声明,因为S<int>未编译。

答案 1 :(得分:0)

如上所述,友元函数f(T)需要是模板函数。当你在main中实例化f(T)时,编译器期望它。