使用 'std::function<void(...)>' 调用 non-void 函数
Using `std::function<void(...)>` to call non-void function
不久前,我使用的std::function
非常像这样:
std::function<void(int)> func = [](int i) -> int { return i; };
基本上,我这样做是因为我想在std::function
中存储不同的函数对象,但我不想限制这些函数的返回类型。由于这似乎有效,我同意了。但我不相信它可以安全使用,而且我也找不到任何文档。有人知道这种使用是否合法吗?或者更一般地说,可以安全地分配给std::function
的对象的规则是什么?
编辑
为了澄清,我关心的问题是lambda函数返回一个int
,而func
是用返回类型void
声明的。我不确定这是否可以,尤其是在呼叫func()
之后。
您的代码有未定义的行为。它可能如你所期望的那样起作用,也可能不起作用。它具有未定义行为的原因是20.8.11.2.1[func.wrap.func.con]/p7:
要求:
F
应为CopyConstructible
。对于参数类型ArgTypes
和返回类型R
,f
应为可调用(20.8.11.2)。
对于返回类型R
,f
是可调用的,f
必须返回一些隐式可转换为std::function
的返回类型的内容(在您的情况下为void
)。并且CCD_ 18不能隐式地转换为CCD_。
我希望您的代码能够用于大多数实现。然而,在至少一个实现(libc++)上,它无法编译:
test.cpp:7:30: error: no viable conversion from 'int (int)' to 'std::function<void (int)>'
std::function<void(int)> ff = f;
^ ~
具有讽刺意味的是,这种行为的理由源于另一个SO问题。
另一个问题是std::function
的使用问题。该问题的解决方案包括让实现在编译时强制执行Requires:子句。相反,这个问题的解决方案是禁止实现强制执行Requires:子句。
您的用例是根据标准定义的
您正在从可调用对象[1]构建std::function
§20.8.11.2.1/7:
template<class F> function(F f);
要求:F应为可复制结构。对于参数类型ArgTypes,f应为可调用的(20.8.11.2)和返回类型R。
那么你的f是可调用的吗?
§20.8.11.2/2规定:
类型为f的可调用对象f对于参数类型ArgTypes是可调用的如果表达式
INVOKE (f, declval<ArgTypes>()..., R)
被视为未赋值的操作数,则返回类型R(第5条),形成良好(20.8.2)
INVOKE
的定义是:
§20.8.2
INVOKE (f, t1, t2, ..., tN)
的定义如下:…处理成员函数/var指针的东西。。。--CCD_ 25。定义隐式转换为
R
的INVOKE (f, t1, t2, ..., tN, R) as INVOKE (f, t1, t2, ..., tN)
。
由于任何类型都可以隐式转换为 正如下面litb所指出的,没有到void的隐式转换,所以这并没有得到很好的定义。void
,因此您的代码应该可以使用符合标准的编译器
[1] :我认为lambda在这里是一个可调用的对象,尽管我没有引用它。您的lambda也可以用作函数指针,因为它不捕获上下文
这看起来可能适用于匿名函数。
报价来源http://www.alorelang.org/release/0.5/doc/std_function.html(这不是来自C++标准库,但看起来他们在使用类似的东西,绑定到C++)
函数对象只能使用函数定义、匿名函数表达式或使用句点(.)运算符访问绑定方法来创建。
另一种可能的方法是将函数指针存储在auto中,如下所示:http://en.wikipedia.org/wiki/Anonymous_function(C++部分)
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 函数调用中参数的顺序重要吗
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在c++类上调用void函数
- 为什么 std::unique 不调用 std::sort?
- 调用专用模板时出错"no matching function for call to [...]"
- 选择要调用的构造函数
- C++为什么尽管我调用了void函数,它却不起作用
- 构造函数正在调用一个使用当前类类型的函数
- 变量没有改变?通过向量的函数调用
- 没有为自己的结构调用列表推回方法
- 调用'begin(int [n])'没有匹配函数
- 什么时候调用析构函数
- 如何用参数值调用函数(仅在运行时已知)
- 是否需要使用 - &gt;运算符在C 中调用成员函数时
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy