我写了一个简单的运算符重载函数,如果我在类内定义它(块注释(,它可以正常工作,但如果在类外定义,它会出错。知道错误在哪里吗?
#include<iostream>
using namespace std;
template<class T>
class vector{
int d;
public:
vector(){
d = 0;
}
vector(T data){
d = data;
}
friend void operator << (vector &v, T data);
/*{
cout << data << endl;
}*/
};
template<class T>
void operator << (vector<T> &v, T data){
cout << data;
}
int main(){
vector<int> v1;
v1 << 10;
return 0;
}
类模板定义中的这个友元函数声明
friend void operator << (vector &v, T data);
不是一个模板函数(尽管如果它是在类中定义的,则它是一个模板化实体(。
另一方面,这个声明在类模板定义之外
template<class T>
void operator << (vector<T> &v, T data){
cout << data;
}
定义了一个模板函数。
在类定义中定义友元函数。在这种情况下,编译器将为类模板的每个使用的专用化生成函数的定义。或者,对于每个使用的类专门化,您必须自己显式地定义(提供(一个单独的非模板朋友函数。
这是一个演示程序
#include<iostream>
template<class T>
class vector{
int d;
public:
vector(){
d = 0;
}
vector(T data){
d = data;
}
friend void operator << (vector &v, T data);
/*{
cout << data << endl;
}*/
};
template<class T>
void operator << (vector<T> &v, T data)
{
std::cout << data;
}
void operator << (vector<int> &v, int data)
{
std::cout << data;
}
int main()
{
vector<int> v1;
v1 << 10;
return 0;
}
程序输出为
10
程序中有两个重载函数CCD_ 1。第一个是类定义中声明的友元非模板函数,第二个是不是类的友元函数的模板函数。对于main中使用的类专用化vector<int>
,您必须在类之外提供非模板友元函数定义。
或者您可以在类中定义friend函数。
问题是如何将一个模板与其他模板交朋友。
没有友谊,你的代码就可以工作(你不能访问私有部分(。
要修复它,你必须与模板交朋友,而不是与常规函数交朋友。既然您定义的函数是一个模板,那么友谊语句就必须表达这一点。
template<class T>
class vector{
int d;
public:
...
template<typename U>
friend void operator<<(vector<U> &v, U data);
};
https://godbolt.org/z/oxcojb
离题:
就我个人而言,我避免友谊(我不记得在代码中使用过友谊(。你的代码我会这样做。
如果您是using namespace std
,然后定义一个名为vector的类,这是std命名空间中的一个名称,编译器将不知道该使用哪一个,这将导致未定义的行为,或者我认为是这样。
此外,由于使用的是模板,因此需要在类中定义该函数,因此会出现错误。