Рассмотрим устаревший шаблон класса с перегруженными операторами сложения +=
и +
.
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)
inline
. - person Deduplicator   schedule 29.09.2014inline
здесь не требуется. В любом случае, ради аргумента, предположим, что весь код содержит только заголовок (обновлено в вопросе) - person TemplateRex   schedule 29.09.2014inline
является избыточным; неявно созданные функции шаблона имеют неявную встроенную связь. - person cdhowie   schedule 29.09.2014inline
в основном используется не для указания того, что функция должна быть встроена (стандарт не требует, чтобы компиляторы учитывалиinline
таким образом), а скорее для указания того, что ODR не применяется (функция разрешена быть определено в нескольких единицах перевода без ошибок). Поскольку неявные экземпляры шаблонов уже освобождены от ODR,inline
на самом деле ничего не делает. Это не одно и то же, но они имеют одинаковый эффект (опять же, что касается неявных экземпляров). - person cdhowie   schedule 29.09.2014+
как на функцию-член:X<Foo> z = x.operator+(y);
Но это не связано с ADL, и также крайне маловероятно, что вы столкнетесь с этим. - person misberner   schedule 29.09.2014