Error: initial value of reference to non-const mus

2019-09-18 18:03发布

问题:

class A
{

public:

    int v;
    A * p;
    A& operator*(const A& a)
    {
        return this->v*a.v// here is a red line under this say error initial value of reference to non-const must be an value
    }
    ~A()
    {
        this;
    }
};

int main()
{
    A a;
    a.p = new A;
    delete a.p;
    return 0;

    system("pause");
    return 0;
}

overloading * operator I cannot use this to represent the object itself. Why this happened.

回答1:

Surely it says that it must be an lvalue. You're trying to return a reference to a temporary. This is bad karma.

Besides, it's not at all what you want. The multiplication operator should definitely return a value, not a reference.

Not sure what your constructor looks like, but assuming it takes an integer:

A operator * (A const& other) const
{
    return A{ v * other.v};
};

Edit:

And actually you should go a step further:

struct A
{
    A& operator *= (A const& other) { v *= other.v; return *this; }
    A(int i) : v(i) {}
private:
    int v;
}

A operator * (A lh, A const& rh)
{
   A res{std::move(lh)};
   res *= rh;
   return res;
}


回答2:

this->v*a.v evaluates to an int. An int cannot be converted to an A&.

Use

A operator*(const A& a) // Return a value, not a reference.
{
   A res;
   res.v = this->v*a.v;
   return res;
}

You should make the member function a const member function too since it does not modify the object.

A operator*(const A& a) const
{
   A res;
   res.v = this->v*a.v;
   return res;
}


回答3:

The result of this->v * a.v is an rvalue, a temporary unnamed value. As a temporary, it cannot bind to a non-const reference. Only lvalues can bind to non-const references. That's what the error "initial value of reference to non-const must be an lvalue" is referring to.

However, you don't want to return a const reference either, you want to return the value by value:

A operator*(const A& a) { … }
 ^ remove &

Note: this will not fix your code completely as you're trying to return an int where you declared to return an A, and int isn't implicitly convertible to A in your current code.