简体   繁体   中英

Overloading “+=” operator: c+=a_times_b works, but c+=a*b does not?

I have two classes A and B. The product A*B should be of type B. Since variables of type B will occupy great amounts of memory, I need to avoid operations like B_1 = B_1 + (A_1 * B_2) , where (A_1 * B_2) would be temporarily allocated. In other words, I need B_1 += A_1 * B_2 .

I have tried this:

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. Why is B_out += product okay but B_out += A_in * B_in is not?

  2. Is there a better way to implement the += -operator for this use? Maybe without defining the helper object pair<A*, B*> ?

The issue is that you're creating a temporary pair<A*, B*> when you multiply A_in*B_in

The signature for your operator+= is

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

You cannot create a non-const reference from a temporary. The compiler * (gcc) tells you as much:

error: cannot bind non-const lvalue reference of type ' std::pair<A*, B*>& ' to an rvalue of type ' std::pair<A*, B*> '

How to read the error message:

The 'rvalue' is your temporary pair<A*, B*> returned from operator* , and the 'non-const lvalue reference' is the targeted pair<A*, B*>&

Solution:

Change operator+= to use a const reference instead:

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

You do not appear to need to modify lhsA_times_rhsB , so you should prefer constness.

Demo

*Clang's error message is actually less informative here because it gets broken into two. The first one is "error: no viable overloaded '+='", and the second one is only slightly more descriptive: "candidate function not viable: expects an l-value for 1st argument"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM