模板类运算符重载的不同错误和警告问题

时间:2017-01-16 14:46:41

标签: 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, 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
};

然而,在我对上述代码进行了一些实验后,我感到很困惑。

  1. 我更改了A类中的友元函数声明
    friend A<T> operator +<> (const A<T>& , const A<T>& );
    friend A<T> operator + (const A<T>& , const A<T>& );
    (删除<>后的operator +
    然后代码可以运行并给出结果,但是我收到警告warning: friend declaration 'A<T> operator+(const A<T>&, const A<T>&)' declares a non-template function

  2. 没有在步骤1中进行修改,我删除了加法运算符重载函数的模板声明。因此,以下代码将被删除:

    template<class T> A<T> operator + (const A<T>& , const A<T>&);

    然后我收到了一个错误:error: template-id 'operator+<>' for 'A<int> operator+(const A<int>&, const A<int>&)' does not match any template declaration

  3. 我在步骤1和步骤2中进行了两次修改,然后在步骤1中收到相同的警告:warning: friend declaration 'A<T> operator+(const A<T>&, const A<T>&)' declares a non-template function

  4. 我对这些修改引起的问题感到困惑。

    1. <>之后operator +的影响是什么? (见第一次修改)
    2. 删除加法运算符重载函数的模板声明的效果是什么? (见第二次修改)
    3. 为什么代码无法运行并在我仅进行第二次修改时返回错误,而在我进行第一次和第二次修改时它可以运行并返回警告?
    4. 提前致谢!

1 个答案:

答案 0 :(得分:1)

案例1 friend A<T> operator +<> (const A<T>& , const A<T>& )实际上是类型T的跟随函数的朋友专长(这是类模板的类型)。

template<class T>
A<T> operator + (const A<T>& , const A<T>&);

如果您想为int这样的特定类型专门设置此功能,请执行以下操作:

template<>
A<int> operator+(const A<int>&, const A<int>&)
{
}

所以你的朋友功能是一个专业的朋友功能。

当您移除<>您的朋友功能时,转为普通朋友功能,但您的实际operator+是模板功能。编译器警告你,因为你的类定义有友元函数的非模板声明(没有模板),但友元函数定义是一个函数模板。将您的朋友功能更改为以下内容以禁止警告。

template<class T1>
friend A<T1> operator+ (const A<T1>&, const A<T1>&);

案例2:您收到该错误,因为operator +的减速度和定义在const参数限定符中有所不同。实际上它们完全是两个不同的功能,第二个功能不是第一个功能的定义。将const添加到函数定义的参数中。

确实,当您删除此代码时:

template<class T>
A<T> operator + (const A<T>& , const A<T>&);

编译器无法为您的朋友减速找到一个带有两个const A<T>&参数的模板函数。