void{} 合法吗?

问题描述 投票:0回答:3

这是this问题的后续。
在评论和答案中不止一次地说

void{}
既不是有效的类型 ID,也不是有效的表达式

很好,很有道理,仅此而已。

然后我浏览了工作草案的[7.1.7.4.1/2]占位符类型推导)。
据说:

[...]
- 对于使用包含占位符类型的返回类型声明的函数中出现的非丢弃

return
语句,
T
是声明的返回类型,
e
return
语句的操作数。如果
return
语句没有操作数,则
e
void{}
;
[...]

那么,

void{}
(概念上)合法吗?
如果正如工作草案中提到的那样可以接受(即使只是作为 - 就好像它是 - 声明一样),那么它确实必须是合法的。作为示例,这意味着
decltype(void{})
也应该有效。
否则,工作草案是否应该使用
void()
而不是
void{}


嗯,说实话,我很确定我没有足够的能力指出工作草案中的错误,所以真正的问题是:我的推理有什么问题?
上面的项目符号中提到的

void{}
到底是什么以及为什么它在本例中是合法的表达方式?

c++ language-lawyer void c++17 return-type-deduction
3个回答
11
投票

对我来说,这听起来像是有人把以前的标准与新标准合并在一起。

之前标准是这么说的:(C++14 N4140, 7.1.6.4.7 [dcl.spec.auto]):

当函数中出现 [...]

return
语句时 使用包含占位符类型、推导的返回类型或变量类型的返回类型进行声明 由其初始值设定项的类型确定。在
return
没有操作数的情况下,初始化器是 被认为是
void()

新标准允许使用

if constexpr
语句,因此需要更改语言以反映这一点。
if constexpr
引出了潜在的 discarded
return
语句的概念(如果
return
位于 constexpr if 的 not-taken 分支中,那么它将被丢弃,并且从其他 return 语句推断出返回类型,if任何)。

新的措辞可能应该是这样的:

对于函数中出现的未丢弃的 return 语句 使用包含占位符类型的返回类型声明,

T
是 声明的返回类型,
e
return
语句的操作数。如果 return 语句没有操作数,则
T
auto
,推导出的返回类型为
void


10
投票

确认了该错误。已经修好了。
这里是讨论(说实话很短)。

所以,答案是 - 不,

void{}
不合法
这是工作草案的措辞错误。


0
投票

在现代 C++ 中,

void()
void{}
之间没有区别。两者都是合法的。 [expr.type.conv] p2 中的当前措辞指出:

否则,如果类型为 cv

void
并且初始化器为
()
{}
(包扩展后,如果有),则表达式是
void
类型的纯右值,不执行初始化。

历史上,曾经存在差异,但 CWG 第 2351 期

void{}
已使
void{}
作为缺陷报告有效,这意味着它追溯适用于 C++11 和更新的标准。

© www.soinside.com 2019 - 2024. All rights reserved.