Операторы не генерируются из других (кроме с / из <=> в C ++ 20):
, обеспечивающий operator <
, не допускает a > b
(что действительно "логически" эквивалентно b < a
). Вы должны реализовать все (даже повторно используя некоторые).
Для классов a += b
- это не сокращение для a = a + b
, а для a.operator +=(b)
или operator +=(a, b)
Таким же образом a = a + b
является сокращение для a.operator=(operator +(a, b))
(или его вариант)
На практике более эффективно реализовать operator+
из operator +=
, чем наоборот.
Даже если пользователь может ожидать аналогичного поведения в соответствии с их именами они являются обычными функциями.
Я уже видел матричный итератор, для которого ++it
увеличивает индекс столбца, тогда как it++
увеличивает индекс строки.
Если +=
были просто сокращением для a = a + <rhs of +=>
оператор перегрузки + должен также неявно overload +=
, если явно не перегружен иначе. Но это не то, что происходит. Это означает, что a += b
не преобразуется в a = a + b
.
(возможно), рациональным, чтобы не генерировать, может быть производительность и контроль:
Vector (для математики) или Хороший пример - матрица:
4 возможных перегрузки
Matrix operator+(Matrix&& lhs, Matrix&& rhs) { return std::move(lhs += rhs); }
Matrix operator+(Matrix&& lhs, const Matrix& rhs) { return std::move(lhs += rhs); }
Matrix operator+(const Matrix& lhs, Matrix&& rhs) { return std::move(rhs += lhs); } // + is symmetrical :)
Matrix operator+(const Matrix& lhs, const Matrix& rhs) { auto tmp{lhs}; return tmp += rhs; }
Побочный эффект решения позволяет придавать операторам различные значения, как «оператор имени»:
if (42 <in> std::vector{4, 8, 15, 16, 23, 42})