为什么绑定函数不适用于解引用迭代器?
Why bind function does not work with dereferencing iterator?
我是 C++ 编程新手。我正在使用 bind
函数将对象与 class 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 Found\n" << 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
) 时,它起作用了,但我不明白。
我知道我可以用 if/else 语句轻松做到这一点,但我想了解更多关于 c++ 的知识。
如 cpprefrence 的 std::bind
页面所述:
The arguments to bind are copied or moved, and are never passed by reference unless wrapped in std::ref
or std::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)}
};
我是 C++ 编程新手。我正在使用 bind
函数将对象与 class 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 Found\n" << 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
) 时,它起作用了,但我不明白。
我知道我可以用 if/else 语句轻松做到这一点,但我想了解更多关于 c++ 的知识。
如 cpprefrence 的 std::bind
页面所述:
The arguments to bind are copied or moved, and are never passed by reference unless wrapped in
std::ref
orstd::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)}
};