【问题标题】:Is it illegal to invoke a std::function<void(Args...)> under the standard?在标准下调用 std::function<void(Args...)> 是否非法?
【发布时间】:2014-10-13 06:33:13
【问题描述】:

所有报价均来自N3797

4/3 [转化]

一个表达式 e 可 隐式转换 到一个类型 吨 当且仅当声明 Tt=e; 形态良好, 对于一些发明的临时变量 t

这意味着没有表达式可以隐式转换为void,因为void t=e 对于所有表达式e 都是非法的。如果evoid 类型的表达式,例如void(3),则更是如此。

所以void 类型的表达式不能隐式转换为void

这导致我们:

20.9.2/2 要求 [func.require]

定义 调用 (f, t1, t2, ..., tN, R) 作为 调用 (f, t1, t2, ..., tN) 隐式转换为 R .

简而言之,当Rvoid 时,INVOKE(f, t1, t2, ..., tN, R) 永远无效,因为没有任何东西(包括void)可以隐式转换为void

因此,所有std::function&lt;void(Args...)&gt; 都具有!*this 属性,因此不能被调用,因为唯一没有!*this 作为后置条件的构造函数(或者不从另一个@987654338 复制这种状态@ 相同类型)需要Callable 的参数之一。

20.9.11.2/7 类模板 功能 [func.wrap.func]

要求: F 应该 可复制构造 . F 应该是可调用的( 20.9.11.2 ) 用于参数类型 参数类型 和返回类型 R .的复制构造函数和析构函数 一种 不会抛出异常。

20.9.11.2/2 类模板 功能 [func.wrap.func]

一个可调用的对象 F 类型 F 是 可调用 对于参数类型 参数类型 和返回类型 R 如果表达式 锡安 调用 (f, declval()..., R) ,被认为是一个未计算的操作数(子句 5 ), 很好 形成( 20.9.2 )。

如上所示,std::function&lt;void(Args...)&gt; 没有 Callable 表达式。

如果以某种方式找到这样的std::function&lt;void(Args...)&gt;,则调用operator() 将是错误的:

调用 [func.wrap.func.inv]

效果: 调用 (f, std::forward(args)..., R) ( 20.9.2 ), 在哪里 F 是目标ob- 项目( 20.9.1 ) 的 *这 .

因为INVOKE(f, std::forward&lt;ArgTypes&gt;(args)..., void) 的所有参数和f 的格式都不正确。

这个推理合理吗?

【问题讨论】:

  • 听起来像是标准的缺陷。
  • 有趣的是is_convertible&lt;void, void&gt;::valuetrue
  • @Praetorian 是的,该类型特征以相当复杂的方式指定([meta.rel]/p4),以“为引用类型、void 类型、数组类型和函数类型提供明确定义的结果。”
  • @Potatoswatter 不,declval 使用 add_rvalue_reference,这是 void 的特殊情况。

标签: c++ c++11 language-lawyer std-function c++14


【解决方案1】:

是的,您的分析是正确的;我得出了同样的结论here

据 Daniel Kruegler 所说,本期 should appear on the library defect list subsequent to the next mailing

相应的库问题已提交,但尚未提交 但在问题列表中可见。

希望一旦它变得可见,我们也会有一个结论性的答案,即是否允许构造一个带有签名返回 voidstd::function 并传递一个带有签名返回非 void (Using `std::function<void(...)>` to call non-void function) 的可调用对象。


更新:这是作为LWG 2420 输入的,它已被解析为支持特殊情况void 返回类型为static_cast 调用函数的结果为void。这意味着可调用的返回非void 可以是std::function&lt;void(...)&gt; 的目标。 LWG2420 作为对 C++14 的发布后更正应用;同时,我所知道的所有编译器都有效地将这种行为作为 C++11 模式的扩展。

【讨论】:

    猜你喜欢
    • 2012-03-09
    • 2011-07-10
    • 2014-12-11
    • 2023-02-07
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-11
    相关资源
    最近更新 更多