Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Operator () and 'using' Declaration: Left operand must be l-value error

The example below illustrates a more complex but not dissimilar problem I've been trying to solve elegantly. I have a set of templates which must be specialized and, in doing so, implement one or both of two interfaces: Readable and Writable, in each specialization. Specific implements both interfaces, and is then tested using main:

class Readable
{
protected:

    int values[3];

public:

    Readable()
    {
        // Does nothing.
    }

    int operator()(int i) const
    {
        return values[i];
    }
};

class Writable : public Readable
{
public:

    Writable()
    {
        // Does nothing.
    }

    using Readable::operator ();
    int& operator()(int i)
    {
        return values[i];
    }
};

class Specific : public Writable
{
};

void write_test(Specific& specific)
{
    // Error C2106: '=' : left operand must be l-value
    specific(0) = 1;
}

int main()
{
    Specific s;
    write_test(s);

    return 0;
}

The code above fails on VS 2008, 2010 with the following:

error C2106: '=' : left operand must be l-value.

This strikes me as odd: have I overlooked something simple? I've compiled and run exactly this code using the [] operator, and all was well (as it should and always has been). It would appear to be some issue relating specifically to the behavior of this operator, an issue I am unfamiliar with.

like image 962
Liam M Avatar asked Jan 04 '12 03:01

Liam M


People also ask

What does left operand must be l value?

Originally Answered: Why do I get error C2106: '=': left operand must be l-value? An l-value is basically a modifiable region. This error typically shows up when you have a constant on the left side of the assignment operator.

What is left operand in C?

The left operand in all assignment expressions must be a modifiable lvalue. The type of the expression is the type of the left operand. The value of the expression is the value of the left operand after the assignment has completed. The result of an assignment expression is not an lvalue.


1 Answers

This is a compiler error: the using declaration should work. To work around the problem just use delegation:

class Writable: public Readable {
    ...
    int operator()(int i) const { return Readable::operator()(i); }
    ...
};

This implementation is longer than the implementation actually delegated to but it avoids problems if the version in Readable ever changes.

like image 102
Dietmar Kühl Avatar answered Nov 09 '22 16:11

Dietmar Kühl