使用`std :: function <void(...)>`来调用非void函数

Ken*_*nde 19 c++ return-type c++11 std-function

前一段时间我用std::function的很像:

std::function<void(int)> func = [](int i) -> int { return i; };
Run Code Online (Sandbox Code Playgroud)

基本上,我这样做是因为我想在a中存储不同的函数对象std::function,但我不想限制这些函数的返回类型.由于这似乎有效,我接受了它.但我不相信它是安全的,我也无法找到任何文件.有谁知道这种用法是否合法?或者更一般地说,对象的规则是什么,可以安全地分配给std::function

编辑

为了澄清,我关心的问题是lambda函数返回一个int,而func声明返回类型void.我不确定这是否正常,特别是一旦打电话func().

How*_*ant 20

您的代码具有未定义的行为.它可能会或可能不会像您期望的那样工作.它有未定义行为的原因是因为20.8.11.2.1 [func.wrap.func.con]/p7:

要求: F应该是CopyConstructible.f对于参数类型ArgTypes和返回类型,应为Callable(20.8.11.2)R.

f使其成为可返回类型的Callable R,f必须返回一些隐式可转换为std::function(void在您的情况下)的返回类型的内容.并且int不能隐含地转换为void.

我希望您的代码能够适用于大多数实现.但是至少在一个实现(libc ++)上,它无法编译:

test.cpp:7:30: error: no viable conversion from 'int (int)' to 'std::function<void (int)>'
    std::function<void(int)> ff = f;
                             ^    ~
Run Code Online (Sandbox Code Playgroud)

具有讽刺意味的是,这种行为的基本原理源于另一个SO问题.

另一个问题是std::function使用问题.该问题的解决方案涉及让实现在编译时强制执行Requires:子句.相反,这个问题的解决方案是禁止实现强制执行Requires:子句.

  • @Yakk:你是对的.对于我来说,在规则发生的时间和方式上更新详细答案并不是一个坏主意. (2认同)