简体   繁体   English

C++ class 在模板中调用的重载运算符 `()` 无法更改成员变量的值

[英]C++ class overloaded operator `()` called in template is not able to change member variable's value

I met a problem when working with templates and overloaded operators in C++.在 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.我想用重载的运算符()创建一个 class Foo ,并且我还想在重载的 () 中更改 class Foo的私有成员变量bar_的值() ,并保留该值以供以后使用。 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 (ie run the overloaded () operator) inside the template.我必须用模板来完成这个:我将Foo class 的 object 传递到模板中,然后在模板中使用对象的名称调用它(即运行重载的()运算符)。 Later, I will call the GetBar public member function on the object to get the value of bar_ .稍后,我会在 object 上调用GetBar公众成员 function 来获取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.在下面的最小可重现示例中,私有成员变量bar_的值在重载()运算符中更改为 2,并在模板中调用。 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.但是,当我稍后尝试使用GetBar公共成员 function 在模板之外获取bar_的值时,它给了我值 1,这是在构造函数中赋予变量bar_的初始值。 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: Output:

print in the operator: bar_ = 2
print outside the operator: bar_ = 1

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_ .您的 function int NodeWalk(T action)采用参数by value ,这意味着您的operator()()的第一个打印是从一个副本调用的,这确实改变了bar_的值。 But once the function ends, the copy is destroyed.但是一旦 function 结束,副本就会被销毁。 The original object declared in main() is unaltered, which is why you see the original value when you try to print again.main()中声明的原始 object 没有改变,这就是为什么当您再次尝试打印时会看到原始值的原因。

If you want the original to be altered, pass the parameter by reference , like this: int NodeWalk(T& action) .如果要更改原始文件,请通过引用传递参数,如下所示: int NodeWalk(T& action)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM