Обратите внимание, что ваша первая наивная реализация очень родная, так как ничего не передается по ссылке. Я предполагаю, что это был действительно наивный пример, и нет необходимости напоминать читателям о преимуществах передачи по ссылке, а не по стоимости.
Обратите внимание, что я использовал операторы, не являющиеся членами-функций, вместо функций-членов, но в итоге результаты (почти) совпадают.
Если вы хотите быть уверенным, что не будет создана необходимая копия, попробуйте версию без оператора:
void add(Matrix & result, const Matrix & lhs, const Matrix & rhs) ;
Если вы хотите сделать это операторским способом (что является моим предпочтительным решением), то вы должны предположить, что operator + создаст временный. Затем вы должны определить и оператор +, и оператор + =:
Matrix & operator += (Matrix & result, const Matrix & rhs) ;
{
// add rhs to result, and return result
return result ;
}
Matrix operator + (const Matrix & lhs, const Matrix & rhs) ;
{
Matrix result(lhs) ;
result += rhs ;
return result ;
}
Теперь вы можете попытаться «оптимизировать» оптимизацию компилятора и записать его как:
Matrix & operator += (Matrix & result, const Matrix & rhs) ;
{
// add rhs to result, and return result
return result ;
}
Matrix operator + (Matrix lhs, const Matrix & rhs)
{
return lhs += rhs ;
}
Как предложено Хербом Саттером в C ++ Стандарты кодирования , 27. Предпочитаю канонические формы арифметических операторов и операторов присваивания , p48-49:
Вариант состоит в том, чтобы оператор @ [@ будучи +, -, что угодно] принимал свой первый параметр по значению. Таким образом, вы сами организуете, что сам компилятор будет выполнять копию для вас неявно, и это может дать компилятору больше свободы в применении оптимизаций.