c++ - 了解 C++ 中函数的值类别

标签 c++

首先,我已经通读了这个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/

相关文章:

c++ - 我应该使用哪个 C++ GUI 库

c++ - 是否有用于限制模板的成语/设计模式?

.net - Microsoft Visual C++ 2003、2005——它们是.Net还是非托管的?

c++ - 如果其他程序在 64 位 Windows 中使用过多,32 位程序是否会内存不足?

c++ - 字符串迭代器与读取每一行不兼容

c++ - 使用 GetDlgItemText() 函数时如何计算 LPWSTR 大小

c++ - 无序自定义对象集的 boost 池

c++ - 带有 std::vector 和 std::queue 的 Prim 算法,我的代码有什么问题?

c++ - 如何在映射中插入值以列表对?

c++ - 如何使用宏检测 Cross GCC 编译器