首先,我已经通读了这个article , 解释 std::move
的功能和 std::forward
.在那篇文章中,有一个示例代码片段,如下所示,我在测试中使用了它。
std::map<std::string, std::function<void()>> commands;
template<typename ftor>
void install_command(std::string name, ftor && handler)
{
commands.insert({
std::move(name),
std::forward<ftor>(handler)
});
}
因为想在实际使用中做实验,所以写了一段简单的代码,如下所示。
#include <iostream>
#include <map>
#include <functional>
using namespace std;
// code copied from above goes here
void fnA() { cout << "Function A." << endl; }
function<void()> fnB = [&]() -> void {
cout << "Function B." << endl;
}
void RunTest() {
install_command("#1", fnA);
install_command("#2", move(fnA));
install_command("#3", fnB);
//install_command("#4", move(fnB));
fnA();
fnB();
for (const auto& p : commands) {
cout << p.first.c_str() << ": " << &p.second << endl;
}
}
int main() {
RunTest();
return 0;
}
程序是用-std=c++11
编译的,执行结果如下。
Function A.
Function B.
#1: 0xaf8088
#2: 0xaf8018
#3: 0xaf81a8
如果我取消注释行 install_command("#4", move(fnB));
,存在运行时错误。
terminate called after throwing an instance of 'std::bad_function_call'
what(): bad_function_call
Function A.
我相信 lambda 函数的所有权已从 function<void()> fnB
转移至 commands["#4"]
,但为什么 fnA()
一边工作fnB()
不是吗?
最佳答案
fnA
是一个常规函数而不是 std::function
作为fnB
当你做的时候
commands.insert({
std::move(name),
std::forward<ftor>(handler)
})
你创造
-
std::function<void()>
来自void(&)()
对于fnA
-
std::function<void()>
来自void(&)()
对于std::move(fnA)
-
std::function<void()>
来自std::function<void()>&
对于fnB
(所以复制构造函数) -
std::function<void()>
来自std::function<void()>&&
对于std::move(fnB)
(所以移动构造函数)
只修改后面的输入参数。
关于c++ - 了解 C++ 中函数的值类别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56681384/