【发布时间】:2014-10-13 06:33:13
【问题描述】:
所有报价均来自N3797。
4/3 [转化]
一个表达式 e 可 隐式转换 到一个类型 吨 当且仅当声明 Tt=e; 形态良好, 对于一些发明的临时变量 t
这意味着没有表达式可以隐式转换为void,因为void t=e 对于所有表达式e 都是非法的。如果e 是void 类型的表达式,例如void(3),则更是如此。
所以void 类型的表达式不能隐式转换为void。
这导致我们:
20.9.2/2 要求 [func.require]
定义 调用 (f, t1, t2, ..., tN, R) 作为 调用 (f, t1, t2, ..., tN) 隐式转换为 R .
简而言之,当R 为void 时,INVOKE(f, t1, t2, ..., tN, R) 永远无效,因为没有任何东西(包括void)可以隐式转换为void。
因此,所有std::function<void(Args...)> 都具有!*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<void(Args...)> 没有 Callable 表达式。
如果以某种方式找到这样的std::function<void(Args...)>,则调用operator() 将是错误的:
调用 [func.wrap.func.inv]
效果: 调用 (f, std::forward(args)..., R) ( 20.9.2 ), 在哪里 F 是目标ob- 项目( 20.9.1 ) 的 *这 .
因为INVOKE(f, std::forward<ArgTypes>(args)..., void) 的所有参数和f 的格式都不正确。
这个推理合理吗?
【问题讨论】:
-
听起来像是标准的缺陷。
-
有趣的是
is_convertible<void, void>::value是true -
@Praetorian 是的,该类型特征以相当复杂的方式指定([meta.rel]/p4),以“为引用类型、void 类型、数组类型和函数类型提供明确定义的结果。”
-
@Potatoswatter 不,
declval使用add_rvalue_reference,这是void的特殊情况。
标签: c++ c++11 language-lawyer std-function c++14