Перегрузка & quot; + = & quot; оператор: c + = a_times_b работает, а c + = a * b — нет?

У меня есть два класса A и B. Продукт A * B должен быть типа B.
Поскольку переменные типа B будут занимать большие объемы памяти, мне нужно избегать таких операций, как B_1 = B_1 + (A_1 * B_2), где (A_1 * B_2) будет временно выделен Другими словами, мне нужно B_1 += A_1 * B_2,

Я попробовал это:

struct A {
int a;
};

struct B {
double b[size];

void operator += (pair<A*, B*> & lhsA_times_rhsB){
A & lhsA = *lhsA_times_rhsB.first;
B & rhsB = *lhsA_times_rhsB.second;

b[lhsA.a] += rhsB.b[lhsA.a];
}
};

inline pair<A*, B*> operator*( A& lhsA,  B& rhsB){
return make_pair(&lhsA, &rhsB);
};

int main(){
A A_in;
B B_in, B_out;

pair<A*, B*> product = A_in*B_in;

B_out += product;    //this works!
B_out += A_in*B_in;  //doesn't work!? (Compiler: "No viable overloaded '+='")

return 0;
}
  1. Почему B_out += product хорошо но B_out += A_in * B_in не является?

  2. Есть ли лучший способ реализовать +=-оператор для такого использования? Может быть, без определения вспомогательного объекта pair<A*, B*>?

1

Решение

Проблема в том, что вы создаете временный pair<A*, B*> когда вы умножаете A_in*B_in

Подпись для вашего operator+= является

 void operator += (pair<A*, B*> & lhsA_times_rhsB)

Вы не можете создать неконстантную ссылку из временного. Компилятор* (GCC) говорит вам так же:

ошибка: невозможно связать неконстантную ссылку lvalue типа ‘std::pair<A*, B*>&‘к значению типа’std::pair<A*, B*>

Как прочитать сообщение об ошибке:

«Rvalue» ваш временный pair<A*, B*> вернулся из operator*и «неконстантная ссылка на значение» является целевой pair<A*, B*>&

Решение:

+ Изменить operator+= вместо этого использовать константную ссылку:

void operator += (const pair<A*, B*>& lhsA_times_rhsB)

Вам не нужно вносить изменения lhsA_times_rhsB, поэтому вы должны предпочесть постоянство.

демонстрация

* Сообщение об ошибке Clang здесь на самом деле менее информативно, потому что оно разбито на две части. Первый из них — «ошибка: перегруженный нет, перегружен ‘+ =’», а второй — лишь немного более описательный: «функция-кандидат недопустима: ожидает l-значение для 1-го аргумента»

4

Другие решения

Других решений пока нет …