用指针重载运算符+

Overloading operator+ with pointers

本文关键字:运算符 重载 指针      更新时间:2023-10-16

我正在做一个关于C++多态性的项目,我有很多指针。我需要重载运算符+,这样我就可以自然地写出以下表达式:

c=a+b;

其中a、b和c被声明为:

A *a,*b,*c;

我知道的基本重载定义是

A &operator+(const A& a)
A &operator=(const A& a)

但我得到以下错误:

类型为"A&"的非常量引用的初始化无效来自"A*const"类型的右值类型为"A*"answers"A*'到二进制"operator+"的无效操作数

我应该如何编写重载运算符,以便可以自然地调用它?

我知道我的以下建议可能不是你想要的,但为了完整性,我试图找到一个带有模板包装类的指针的解决方案,允许重载operator+。我想知道查找规则、模板参数和类型转换的组合到底能实现什么。事实证明,operator+的"自然"使用似乎是不可能的,但显式调用是可行的。这是我的代码:

/** A wrapper class around arbitrary pointer types */
template<class TPtr> class MyPtrT
{
public:
TPtr ptr;
MyPtrT(const TPtr p = 0) :ptr(p)    
{}
};
/** A plus operator on all MyPtrTs */
template<class T> 
const MyPtrT<T>& 
operator+(const MyPtrT<T> &l, const MyPtrT<T> &r) 
{ 
return l; 
}
MyPtrT<int *> mp1, mp2, mp3;
int *ip;

好的,这些声明的作用是什么?

// This works (template type explicit) ...
mp3 = operator+<int *>(ip, ip);
// ... and this works (of course,
// arguments match template declaration) ...
mp3 = mp1 + mp2;

什么没有(gcc 4.8.3)?

mp3 = mp1 + ip;

错误为:

smartpointplus.cpp:33:12: error: no match for ‘operator+’ (operand types are ‘MyPtrT<int*>’ and ‘int*’)
mp3 = mp1 + ip;
^
smartpointplus.cpp:33:12: note: candidate is:
smartpointplus.cpp:13:1: note: template<class T> const MyPtrT<T>& operator+(const MyPtrT<T>&, const MyPtrT<T>&)
operator+(const MyPtrT<T> &l, const MyPtrT<T> &r)
^
smartpointplus.cpp:13:1: note:   template argument deduction/substitution failed:
smartpointplus.cpp:33:14: note:   mismatched types ‘const MyPtrT<T>’ and ‘int*’

我不太清楚编译器为什么不从int*参数构造MyPtrT。它确实看到了正确的功能。也许我的ctor出了什么问题?

mp3 = operator+(ip, ip);

错误消息类似。考虑了模板函数,但编译器无法转换参数。

smartpointplus.cpp:36:24: error: no matching function for call to ‘operator+(int*&, int*&)’
mp3 = operator+(ip, ip);
^
smartpointplus.cpp:36:24: note: candidate is:
smartpointplus.cpp:13:1: note: template<class T> const MyPtrT<T>& operator+(const MyPtrT<T>&, const MyPtrT<T>&)
operator+(const MyPtrT<T> &l, const MyPtrT<T> &r)
^
smartpointplus.cpp:13:1: note:   template argument deduction/substitution failed:
smartpointplus.cpp:36:24: note:   mismatched types ‘const MyPtrT<T>’ and ‘int*’
mp3 = operator+(ip, ip);

operator+(ip, ip)(自动尝试推断模板类型)不起作用,这有点令人难过。这限制了可用性;-)。必须使用该运算符对所有函数进行模板化,以避免为每次调用显式提供模板类型。相比之下,下面的中缀表示法甚至没有考虑模板运算符:

mp3 = ip + ip;

错误消息很短:

smartpointplus.cpp:38:13: error: invalid operands of types ‘int*’ and ‘int*’ to binary ‘operator+’
mp3 = ip + ip;

我一直认为运算符调用的中缀和函数式表示法只是表示法的区别,但显然它们也改变了查找规则。

tl;dr:OP想要的(带指针参数的中缀加运算)即使使用模板包装类afaict也不起作用。

赋值运算符是一个特殊的成员方法(请参阅http://en.cppreference.com/w/cpp/language/operators和http://en.cppreference.com/w/cpp/language/as_operator)并且C++在他的第一个标准之后不允许运算符覆盖指针(以前,一些实现允许这样做)。