我没有收到此错误:
#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。
答案 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)时,编译器期望它。