Home > Software engineering >  C class overloaded operator `()` called in template is not able to change member variable's v
C class overloaded operator `()` called in template is not able to change member variable's v

Time:07-27

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).

  • Related