c++ - 模板类的友元运算符

标签 c++ templates c++11 operator-overloading friend-function

我有一个模板类,我向它声明了 2 operator+方法。他们的声明是:

1) const MyClass<T> operator+ (int num) const;

2) friend const MyClass<T> operator+ <>(int num, const MyClass<T>& other);

正在关注 this FAQ , .hpp 文件看起来像这样:

//forward declaration of the class.
template<class T>
class MyClass;

//forward declaration of the operator+
template<class T>
const MyClass<T> operator+ (int num, const MyClass<T>& other);

template<class T>
class MyClass {
public:
    ...
    const MyClass<T> operator+ (int num) const;
    friend const MyClass<T> operator+ <>(int num, const MyClass<T>& other);
    ...
};

(后来我有了这些方法的定义)。

注意 2 operator+方法在不同情况下使用:

第一个

MyClass mc;
mc+5;

第二个

MyClass mc;
5+mc;

但出于某种原因,当我用 g++(版本 4.8.2,如果重要的话)编译它时,出现错误:

declaration of ‘operator+’ as non-function
   friend const MyClass<T> operator+ <>(int num, const MyClass<T>& other);

请注意,错误指的是 friend operator+方法

但是,如果我删除第一个 operator+ 的声明方法(即只留下 friend 一个),然后一切都编译得很好!

这是怎么回事?

最佳答案

不知道为什么,但是切换顺序可以编译(将尝试找到解释):

//forward declaration of the class.
template<class T>
class MyClass;

//forward declaration of the operator+
template<class T>
const MyClass<T> operator+(int num, const MyClass<T>& other);

template<class T>
class MyClass {
public:
  friend const MyClass<T> operator+<>(int num, const MyClass<T>& other);
  const MyClass<T> operator+ (int num) const;

};

编辑

感谢 Maksim 指出我的怀疑是正确的。发生的情况是两个运算符的名称发生冲突,从而导致错误。通常第二个运算符的名称中包含类名,但是由于在类声明中您在类范围内,因此名称会发生​​冲突。如果非类成员运算符位于不同的命名空间中,例如:

//forward declaration of the class.
template<class T>
class MyClass;

//forward declaration of the operator+
namespace Foo
{
template<class T>
const MyClass<T> operator+(int num, const MyClass<T>& other);
}
template<class T>
class MyClass {
public:
  const MyClass<T> operator+ (int num) const;
  friend const MyClass<T> Foo::operator+<>(int num, const MyClass<T>& other);

};

using namespace Foo;

int main()
{
  MyClass<int> a;
  5 + a;
}

这很好,因为名称会不同。此外,如果您将它们用作另一个对象的 friend ,那也很好:

//forward declaration of the class.
template<class T>
class MyClass;

//forward declaration of the operator+
template<class T>
const MyClass<T> operator+(int num, const MyClass<T>& other);

template<class T>
class MyClass {
public:
  const MyClass<T> operator+ (int num) const;
};

template <typename T>
class Foo
{
friend const MyClass<T> operator+<>(int num, const MyClass<T>& other);
friend const MyClass<T> MyClass<T>::operator+(int num);
};

int main()
{
  MyClass<int> a;
  5 + a;
}

我希望这能解释这些例子说明原因。

关于c++ - 模板类的友元运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32072957/

相关文章:

c++ - 打印最长的字符串重复 M 次

c++ - 关于C++模板参数的问题

c++ - 模板 vector

java - 通用 java 函数使用的 "Class type"的 "type parameter"

c++ - 复制构造函数相关的编译错误

c++ - std::array 位是否与旧的 C 数组兼容?

C++ shared_ptr 释放所有权

c++ - 在 Windows 下处理多个客户端连接的最佳方法(不使用线程)?

c++ - 当许多 unordered_map<string, double> 具有完全相同的字符串设置为键时如何节省内存

c++ - 使用类型别名,例如使用 A = int(int)