我在学习模板时遇到过以下练习:
#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;
}
Run Code Online (Sandbox Code Playgroud)
该代码片段应该在编译期间产生错误,而且确实如此。这是链接器错误,但我无法理解。
我尝试更改几行代码,错误似乎是由模板的安装引起的operator<<,因为删除该模板并编写特定的运算符使代码可以工作。我还感觉模板会被实例化多次,而不仅仅是int.
然而,据我有限的知识,模板定义似乎很好。我缺少什么?
确切的错误(VS 2017)是: Error LNK2019: unresolved external symbol "class std::basic_ostream > & __cdecl operator<<(class std::basic_ostream > &,class A const &)" (??6@YAAEAV?$ basic_ostream@DU?$char_traits@D@std@@@std@@AEAV01@AEBV?$A@H@@@Z) 在 main 函数中引用
您需要将友元函数声明为模板:
class A {
...
template <class U> // <-- NOTICE ---------------v
friend ostream & operator<<(ostream & c, const A<U> & v);
...
Run Code Online (Sandbox Code Playgroud)
或者更好的是,使用更安全的方法,尽管有点冗长:
#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;
}
Run Code Online (Sandbox Code Playgroud)
请参阅此页面了解更多详细信息。
| 归档时间: |
|
| 查看次数: |
539 次 |
| 最近记录: |