I met a problem when working with templates and overloaded operators in C .
I want to create a class Foo
with an overloaded operator ()
, and I also want to change the value of a private member variable bar_
of class Foo
inside the overloaded ()
, and keep that value for later use. I have to finish this with a template: I will pass an object of the Foo
class into the template, and then call it with the object's name (i.e. run the overloaded ()
operator) inside the template. Later, I will call the GetBar
public member function on the object to get the value of bar_
.
In the following minimal reproducible example, the value of the private member variable bar_
is changed to 2 in the overloaded ()
operator, and is called in the template. However, when I tried to get the value of bar_
later outside the template using the GetBar
public member function, it gives me the value 1, which is the initial value given to the variable bar_
in the constructor. Thus, the value change in the ()
operator doesn't work.
Does anyone have an idea what is happening here? I am not sure why the value change is not saved in the variable.
#include <iostream>
#include <unordered_map>
using std::unordered_map;
using std::cout;
using std::endl;
using std::unordered_map;
class Foo {
public:
Foo() : bar_(1) {}
void operator()() {
bar_ = 2;
std::cout << "print in the operator: bar_ = " << bar_ << std::endl;
return;
}
size_t GetBar() {
return bar_;
}
private:
int bar_;
};
template <typename T>
int NodeWalk(T action) {
action();
return 0;
}
int main()
{
Foo obj;
NodeWalk(obj);
cout << "print out the operator: bar_ = " << obj.GetBar() << endl;
return 0;
}
Output:
print in the operator: bar_ = 2
print outside the operator: bar_ = 1
CodePudding user response:
Your function int NodeWalk(T action)
takes the parameter by value, which means that the first print from your operator()()
is called from a copy, which did alter the value of bar_
. But once the function ends, the copy is destroyed. The original object declared in main()
is unaltered, which is why you see the original value when you try to print again.
If you want the original to be altered, pass the parameter by reference, like this: int NodeWalk(T& action)
.