-1

I have a class called CircuitProfiler that has a public member function switchState. Below is the code for it:

void CircuitProfiler::switchState(int index) { if (profilingNode) { switch (index) { case 0: node->getVoltage().isKnown = !node->getVoltage().isKnown; break; } } } 

The code I am having trouble with is the line:

node->getVoltage().isKnown = !node->getVoltage().isKnown;

I am getting error that says "expression must be a modifiable lvalue". There is a red line under node.

node is a pointer to an instance of a Node class that I created. node a private data member of CircuitProfiler. It is declared in CircuitProfiler as Node* node;

Node has a private data member called voltage, and getVoltage is a public member function of Node that simply returns voltage. voltage is declared in Node as VariableValue<float> voltage; and the code for getVoltage is:

VariableValue<float> Node::getVoltage() { return voltage; } 

voltage is an instance of a simple struct called VariableValue, the code for which is below.

template <class T> struct VariableValue { T value; bool isKnown; }; 

So why am I getting the error "expression must be a modifiable value"? Let me know if I need to provide any more information.

3
  • 2
    you'd likely want VariableValue<float>& Node::getVoltage(), i.e., return by reference. Otherwise you'd be modifying a temporary in the = call. Commented Aug 4, 2022 at 22:21
  • 1
    Read the error more carefully, you should find it say "modifiable lvalue", not "modifiable value" Commented Aug 4, 2022 at 22:45
  • GetVoltage() returns by value so it returns an rvalue (loosely, a value that is on the right of an assignment expression). Among other things that means the returned value will cease to exist at the end of the current statement, and modifications to it are meaningless. C++, by design, treats such deeds as a diagnosable error. If you want to modify the underlying voltage object that it returns, change the function so it returns a reference, not by value. Commented Aug 5, 2022 at 1:49

1 Answer 1

1

You are essentially saying (MCVE):

struct S { int i; }; // S as VariableValue<float> S f() { return S{}; } // f as getVoltage f().i = 1; // i as isKnown 

You return a temporary in getVoltage(), which does not bind to an lvalue argument of operator=().

Likely you wanted to return voltage by reference in getVoltage(), if you wanted to use it this way, i.e.,

VariableValue<float>& Node::getVoltage() { return voltage; } 

You might also define a const version of it.

Sign up to request clarification or add additional context in comments.

2 Comments

Minor nitpick: since the operands are both built-in type, = here is the built-in assignment operator, it is not a function nor an overloaded operator. The built-in assignment operator requires a modifiable lvalue as left operand; operator=() does not have such a restriction
Thank you. Your exact solution alone was not enough, but I solved my issue by also modifying the switchState function such that it uses an intermediate VariableValue<float> instance.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.