我已经编写了一个简单的操作符重载函数,如果在类内定义它,它可以正常工作(块注释),但是如果在类外定义它,它就会出错。 知道哪里出错了吗?
#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;
}
定义模板函数。
要么在类定义中定义friend函数。 在这种情况下,编译器将为每个使用的类模板专门化生成函数的定义。 或者,对于每个使用的类专门化,您必须自己显式地定义(提供)一个单独的非模板友元函数。
这是一个演示程序
#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
在程序中有两个重载函数运算符<<
。 第一个是在类定义中声明的友元非模板函数,第二个是不是类的友元函数的模板函数。 对于main中使用的类专门化向量
,必须在类之外提供非模板友元函数定义。
也可以在类中定义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
离题:
就我个人而言,我避免友谊(我不记得在我的代码中使用过它)。 你的代码我会这样做。
如果使用名称空间std
,然后定义一个名为vector的类(来自std名称空间的名称),编译器将不知道使用哪个类,这将导致未定义的行为,或者我认为是这样。
另外,由于您使用的是模板,因此需要在类内部定义该函数,因此您得到了错误。