为什么bind函数不能与解引用迭代器一起工作?



我是c++编程新手。我使用bind函数绑定一个对象与类setter并调用setter。当我试图将迭代器解引用为bind函数中的对象时,对象变量不会改变。然而,当我只是传递迭代器作为对象在bind函数,它的工作。有人能给我解释一下为什么会这样吗?

string name;
char temp;
bool manager;
cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
cout << "Employee Name: ", getline(cin, name, 'n');
auto employee = find(employee_list.begin(), employee_list.end(), name);
if (employee != employee_list.end()){
cout << "Change Detail " << endl;
cout << "1. Name" << endl;
cout << "2. Phone" << endl;
cout << "3. Address" << endl;
string choice;
string new_value;
map<string, function<void(string_view)>> subMenu;
do{
cout << "Selection: ", cin >> choice;
cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
cout << "New Value: ", getline(cin, new_value, 'n');
subMenu = {
{"1", bind(&Employee::set_name, *employee, new_value)},
{"2", bind(&Employee::set_phone, *employee, new_value)},
{"3", bind(&Employee::set_address, *employee, new_value)}
};
if(subMenu.find(choice) == subMenu.end()){
cout << "nSelection Not Foundn" << endl;
}
}
while (subMenu.find(choice) == subMenu.end());
auto selection = subMenu.find(choice)->second;
selection(new_value);
cout << "Operation complete" << right << endl;  
}

Setter函数:

void Employee::set_name(std::string_view p_name){
std::cout << "Set Name: " << std::endl;
std::cout << "Old value: " << name << std::endl;
name = p_name;
std::cout << "New value: " << name << std::endl;

}
void Employee::set_phone(std::string_view p_phone){
phone = p_phone;
}
void Employee::set_address(std::string_view p_address){
address = p_address;
}

当我尝试使用*employee时,它不会改变对象的变量。然而,当我只是传递由find函数返回的迭代器(employee)时,它有效,我不明白这一点。我知道我可以很容易地做到这一点,如果/else语句,但我想学习更多关于c++。

std::bind页面上的cppreference所述:

要绑定的参数被复制或移动,并且永远不会通过引用传递,除非在std::refstd::cref中包装。

如果你想改变*employee所指向的对象,你应该将它们包装在std::reference_wrapper中,例如通过辅助函数std::ref:

subMenu = {
{"1", bind(&Employee::set_name, std::ref(*employee), new_value)},
{"2", bind(&Employee::set_phone, std::ref(*employee), new_value)},
{"3", bind(&Employee::set_address, std::ref(*employee), new_value)}
};

最新更新