Основным недостатком реализации составного присваивания в качестве нечленов является несоответствие с простым оператором присваивания (копирования или перемещения).Простое назначение копирования или перемещения (т. Е. operator=
) должно быть должно быть реализовано как функция-член, иначе компилятор прямо отклонит код.
Учитывая, что назначение копирования / перемещения должны быть реализованы как функции-члены, многие предпочитают также выполнять составные присваивания в качестве членов.
Кроме этого, этот код:
template <typename _type, typename _input_type>
inline myClass<_type> operator+(myClass<_type>& _o1, myClass<_input_type> _o2) {
return _o1+=_o2;
};
... is, IMOочень нежелательно.Общий стиль хорош, но вы перепутали, какой операнд должен передаваться по значению, а какой - по ссылке.В результате он может быть излишне неэффективным, и (намного хуже) изменяют свой левый операнд, поэтому он действительно действует как +=
вместо +
.То, что вам почти наверняка нужно, больше похоже на это:
template <typename _type, typename _input_type>
inline myClass<_type> operator+(myClass<_type> _o1, myClass<_input_type> const &_o2)
{
return _o1+=_o2;
};
Здесь мы передаем левый операнд по значению, поэтому при вызове функции временное значение создается и инициализируется из левого операнда.Затем мы изменяем это временное значение ( без изменения оригинала) и возвращаем его.Так как мы его возвращаем, будет elision copy (необязательный для старых компиляторов, но обязательный, начиная с C ++ 17), что означает, что обычно он будет просто ссылкой на место назначения, так эффективно, что-то вроде: a = b + c;
будеттрактоваться как: a = b; a += c;
.Так как нам нужно только предыдущее значение правого операнда, мы передаем его как ссылку на const, чтобы избежать ненужной копии (хотя, в зависимости от типа, передача по ссылке может не набрать достаточного количества для заботы или даже может быть потерей).Но это может быть большой выигрыш, и редко это больше, чем крошечная потеря).