A refatoração de um operador sobrecarregado em uma função que não é membro pode quebrar algum código?
Considere um modelo de classe herdado com operadores de adição sobrecarregados+=
e+
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;
};
Após a revisão do código, observa-se que+
é implementável em termos de+=
, então por que não torná-lo um não-membro (e ter simetria garantida para argumentos à esquerda e à direita)?
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;
}
Parece bastante seguro, porque toda expressão válida usando+
e+=
reter seu significado semântico original.
Pergunta, questão: pode a refatoração deoperator+
de uma função membro para uma função não membro quebra algum código?
Definição de quebra (pior para o melhor)
será compilado um novo código que não foi compilado no cenário antigocódigo antigo não compilará que compilou no cenário antigonovo código chamará silenciosamente um diferenteoperator+
(da classe base ou do namespace associado arrastado pela ADL)