C++ 模板类运算符重载的不同错误和警告问题
在重载模板类的加法运算符时,我遇到了不同的问题 我终于找到了一个解决方案,下面的代码可以毫无问题地工作C++ 模板类运算符重载的不同错误和警告问题,c++,c++11,templates,C++,C++11,Templates,在重载模板类的加法运算符时,我遇到了不同的问题 我终于找到了一个解决方案,下面的代码可以毫无问题地工作 template<class T> class A; template<class T> A<T> operator + (const A<T>& , const A<T>&); template <class T> A<T> operator+ (A<T> & a1,
template<class T>
class A;
template<class T>
A<T> operator + (const A<T>& , const A<T>&);
template <class T>
A<T> operator+ (A<T> & a1, A<T> & a2){
//the definition of the function
}
template <class T>
class A{
friend A<T> operator +<> (const A<T>& , const A<T>& );
private: //...whatever
public: //...whatever
};
模板
甲级;
模板
运算符+(常数A&,常数A&);
模板
A运算符+(A&a1、A&a2){
//函数的定义
}
模板
甲级{
友元A运算符+(常数A&,常数A&);
二等兵:/…随便什么
公众://…随便什么
};
然而,在我对上述代码进行了一些实验之后,我感到非常困惑。
从
朋友A操作符+(常数A&,常数A&)代码>
到友元A运算符+(常数A&,常数A&)代码>
(删除运算符+
后的
)
然后,代码可以运行并给出结果,但我得到一个警告:警告:友元声明“运算符+(常量a&,常量a&)”声明一个非模板函数
模板
运算符+(常数A&,常数A&)代码>
然后我得到一个错误:error:A operator+(const A&,const A&)的模板id“operator+”与任何模板声明都不匹配
警告:友元声明'A operator+(const A&,const A&')声明了一个非模板函数
我对这些修改引起的问题感到困惑
操作符+
之后的
效果如何?(参见第一次修改)提前谢谢 案例1:
友元A操作符+(常数A&,常数A&)
实际上是类型T
的以下函数的友元特化(这是类模板的类型)
所以你的朋友函数是一个特殊的朋友函数
当您删除
时,您的好友函数将变为普通好友函数,但实际的运算符+
是一个模板函数。编译器正在警告您,因为您的类定义具有友元函数的非模板声明(没有模板),但友元函数定义是函数模板。将您的friend函数更改为以下内容以抑制警告
template<class T1>
friend A<T1> operator+ (const A<T1>&, const A<T1>&);
编译器找不到使用两个
常量a&
参数的模板函数。谢谢!我在operator+
的定义中添加了const
,效果很好。但是我的问题中的第一个代码片段(没有修改1或2)在其操作符+
定义中仍然没有常量,而在其声明中有常量。为什么它可以毫无问题地运行?@llxxee您正在声明两个不同的函数,它们的参数的常数不同。其中一个是类的朋友,没有定义,另一个有定义,但因为它的签名不同于朋友函数,所以它不会是类的朋友。编译器不会抱怨,因为第一个函数从不调用。如果您添加两个常量A
,您将得到未解决的外部
链接器错误,或者如果您访问操作符+
内部的A
的私有成员变量,您将看到编译器抱怨无法访问的私有成员@llxxee抱歉我的英语不好。有时候我脑子里有一个句子,但我不能用英语很好地表达出来。你的解释对我来说很清楚:)顺便说一下,我发现如果我声明一个函数,比如void f(const int m)
,而不定义const
likevoid f(int m){cout@llxxee您的示例只是一个特例。有关本例的更多信息,请参见此处:但您可以将参数更改为int&并使用const
变量调用您的函数。(const int i=5;f(i);
)您将看到您将得到未解析符号
错误。
template<>
A<int> operator+(const A<int>&, const A<int>&)
{
}
template<class T1>
friend A<T1> operator+ (const A<T1>&, const A<T1>&);
template<class T>
A<T> operator + (const A<T>& , const A<T>&);