考虑一个带有重载加法运算符的遗留类模板+=
和+
template<class T>
class X
{
public:
X() = default;
/* implicict */ X(T v): val(v) {}
X<T>& operator+=(X<T> const& rhs) { val += rhs.val; return *this; }
X<T> operator+ (X<T> const& rhs) const { return X<T>(*this) += rhs; }
private:
T val;
};
在代码审查中,观察到它+
是可以实现的+=
,那么为什么不让它成为一个非成员(并且保证左右参数的对称性)?
template<class T>
class X
{
public:
X() = default;
/* implicit */ X(T v): val(v) {}
X<T>& operator+=(X<T> const& rhs) { val += rhs.val; return *this; }
private:
T val;
};
template<class T>
X<T> operator+(X<T> const& lhs, X<T> const& rhs)
{
return X<T>(lhs) += rhs;
}
它看起来足够安全,因为所有有效的表达都使用+
并+=
保留了它们原来的语义含义。
问题:从成员函数重构operator+
为非成员函数会破坏任何代码吗?
破损的定义(从最坏到最好)
- 将编译在旧方案下未编译的新代码
- 在旧场景下编译的旧代码将无法编译
- 新代码将静默调用不同的
operator+
(从通过 ADL 拖入的基类或关联命名空间)