Why is this "expression" not modifiable? [duplicate] - c++

This question already has answers here:
What does "expression must be a modifiable lvalue" mean?
(3 answers)
What are rvalues, lvalues, xvalues, glvalues, and prvalues?
(13 answers)
Closed 7 months ago.
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.

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.

Related

C++: Cannot use designated initializers on extended structs/classes [duplicate]

This question already has answers here:
Designated initializers in C++20
(2 answers)
Closed 9 months ago.
I am trying to figure out a way to use designated initializers to build a struct, which has been extended off of another one. In my use case, the struct S is a domain object, and the struct S2 adds some application-specific logic for converting it to/from json. As far as I can tell, you cannot use designated initializers if you have a "real" constructor, but all is well if you have a static method returning a new instance for you.
I have a MVP like so (view in Godbolt):
#include <iostream>
struct S {
int i;
};
struct S2 : public S {
static S2 create() {
return S2 { .i = 1234 };
}
};
int main() {
std::cout << S2::create().i;
}
When building (using -std=c++20), I get the following error:
<source>:9:31: error: 'S2' has no non-static data member named 'i'
9 | return S2 { .i = 1234 };
| ^
I expect that the i field would be carried over and initialized, but it isn't.
Am I trying to do something C++ cannot support?
i is data member of S, but not S2.
You can add another braces referring to the base subobject, e.g.
return S2 { {.i = 1234} };
Or you can just take advantage of brace elision:
return S2 { 1234 };

Can anybody explain a typical scenario where Const function is necessary? [duplicate]

This question already has answers here:
Meaning of 'const' last in a function declaration of a class?
(12 answers)
Closed 2 years ago.
#include<iostream>
using namespace std;
class Test {
int value;
public:
Test(int v = 0) {value = v;}
// We get compiler error if we add a line like "value = 100;"
// in this function.
int getValue() const {return value;}
};
int main() {
Test t(20);
cout<<t.getValue();
return 0;
}
Can anybody explain a typical practical scenario where Const function is necessary?
The const member functions are the functions which are declared as constant in the program. The object called by these functions cannot be modified. It is recommended to use const keyword so that accidental changes to object are avoided.
A const member function can be called by any type of object. Non-const functions can be called by non-const objects only.
https://www.tutorialspoint.com/const-member-functions-in-cplusplus

std::move with && (rvalue reference) as a member function return type [duplicate]

This question already has answers here:
Is returning by rvalue reference more efficient?
(2 answers)
Should I return an rvalue reference parameter by rvalue reference?
(4 answers)
Closed 5 years ago.
I just want to initialize a member data oneObj of class Two as below which compiles fine. I would like to know whether it is advisable to use std::move and && together to initialize an object or just pass the oneObj as a reference to InitObjOne as follows InitObjOne(One & obj) and initialize it. is there any advantage over another. Please clarify.
Note: The InitObjOne need to perform few actions for creating an object of One, I've just given a skeleton of the functionalities here.
#include <iostream>
using namespace std;
class One
{
public:
int x;
};
class Two
{
public:
Two();
private:
One oneObj;
One && InitObjOne();
};
Two::Two() : oneObj(InitObjOne())
{
}
One && Two::InitObjOne()
{
One aObjOne;
return std::move(aObjOne);
}
int main()
{
Two two;
return 0;
}

this->member VS member in C++ [duplicate]

This question already has answers here:
Is there any reason to use this->
(16 answers)
Closed 7 years ago.
what is the difference between this:
int MyClass::getId() {
return this->id;
}
and this:
int MyClass::getId() {
return id;
}
in C++?
The first example limits the scope where the name "id" is looked up to members of class MyClass.
the second example does not.
This makes a difference if e.g. MyClass has no member "id", or if the current method has a local variable or parameter with the same name.
It depends on the context. Examples:
template <typename> struct X { int a; };
int b;
template <typename T> struct Foo : X<T> {
int f() {
return this->a; // OK
// return a; // Error
}
int g() {
// return this->b; // Error
return b; // OK
}
};
Assuming your class has a member variable named id, there is no difference. Even if you have a global id variable, the member variable always takes precedence.
Your next question is:
So why does exist the this keyword?
There are some situations you absolutely need it.
One example is you want a function returning a pointer/reference(*) to the object itself:
return *this; //reference
return this; //pointer
Other is you want to pass it as an argument to a function
some_function(*this); //reference(&) or value, depends on some_function signature
some_function(this); //pointer
It can also be used in this->id, just for legibility, just for the next person reading the code immediately know id is a constituent of the class instead of a global, having no functional advantage.
If you use a debugger, the this may be also an inspectable variable by it.

What does const mean following a function/method signature? [duplicate]

This question already has answers here:
Meaning of 'const' last in a function declaration of a class?
(12 answers)
Closed 5 years ago.
According to MSDN: "When following a member function's parameter list, the const keyword specifies that the function does not modify the object for which it is invoked."
Could someone clarify this a bit? Does it mean that the function cannot modify any of the object's members?
bool AnalogClockPlugin::isInitialized() const
{
return initialized;
}
It means that the method do not modify member variables (except for the members declared as mutable), so it can be called on constant instances of the class.
class A
{
public:
int foo() { return 42; }
int bar() const { return 42; }
};
void test(const A& a)
{
// Will fail
a.foo();
// Will work
a.bar();
}
Note also, that while the member function cannot modify member variables not marked as mutable, if the member variables are pointers, the member function may not be able to modify the pointer value (i.e. the address to which the pointer points to), but it can modify what the pointer points to (the actual memory region).
So for example:
class C
{
public:
void member() const
{
p = 0; // This is not allowed; you are modifying the member variable
// This is allowed; the member variable is still the same, but what it points to is different (and can be changed)
*p = 0;
}
private:
int *p;
};
The compiler won’t allow a const member function to change *this or to
invoke a non-const member function for this object
As answered by #delroth it means that the member function doesn't modify any memeber variable except those declared as mutable. You can see a good FAQ about const correctness in C++ here