好友函数上的模板链接器错误

Templates linker error on friend function

本文关键字:链接 错误 函数 好友      更新时间:2023-10-16

我在学习模板时遇到了以下练习:

#include <iostream>
using namespace std;
template <class T>
class A {
    T _v;
public:
    A() {}
    A(T v) : _v(v) {}
    friend ostream & operator<<(ostream & c, const A<T> & v);
};
template <class T>
ostream & operator<<(ostream & c, const A<T> & v){
    c << v._v; return c;
}
int main()
{
    A<int>a(10);
    cout << a << endl;
    return 0;
}

此代码片段应该在编译过程中产生错误,并且确实如此。这是一个链接器错误,但我无法理解。

我尝试更改几行代码,但错误似乎是由模板operator<<的插入引起的,因为删除该模板并编写特定的运算符会使代码正常工作。我也觉得模板被多次实例化,不仅仅是为了int.

但是,据我有限的知识,模板定义似乎很好。我错过了什么?

确切的错误(VS 2017)是:错误 LNK2019:未解析的外部符号"class std::basic_ostream> & __cdecl 运算符<<(class std::basic_ostream> &,class A const &)"(??6@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AEAV01@AEBV?$A@H@@@Z) 在函数 main 中引用

你需要将 friend 函数声明为模板:

class A {
   ...
   template <class U>  // <-- NOTICE ---------------v
   friend ostream & operator<<(ostream & c, const A<U> & v);
   ...

或者更好的是,使用更安全的方法,尽管更冗长:

#include <iostream>
using namespace std;
template <class T>
class A;
template <class T>
ostream& operator<<(ostream& c, const A<T>& v);
template <class T>
class A {
    T _v;
    public:
    A() {}
    A(T v) : _v(v) {}
    friend ostream& operator<< <T>(ostream& c, const A<T>& v);
};
template <class T>
ostream& operator<<(ostream& c, const A<T>& v) {
    c << v._v;
    return c;
}
int main() {
    A<int> a(10);
    cout << a << endl;
    return 0;
}

有关更多详细信息,请参阅此页面。