c++ - switch 语句中 case 标签后语句中的重新声明
问题描述
考虑这个例子
#include <iostream>
int main(){
switch(int a = 1){ //#condition
case 1: switch(int a = 2){}
case 2: switch(int a = 2){}
}
}
为什么a
在这个例子中重新声明的格式正确?
根据以下规则:
在 init-statement、for-range-declaration 以及 if、while、for 和 switch 语句的条件中声明的名称对于 if、while、for 或 switch 语句(包括受控语句)是局部的,并且不得在该语句的后续条件中或受控语句的最外层块(或者,对于 if 语句,任何最外层块)中重新声明。
IIUC,无论是声明中的声明switch(int a = 2){}
还是switch(int a = 2){}
都在受控语句的最外层,这是一个复合语句。
作为对比:
#include <iostream>
int main(){
switch(int a = 1){ //#condition
case 1: int a = 2;
}
}
a
after的重新声明case 1
是不正确的,因为它是在该语句的最外面的块中重新声明的。
阐明
根据stmt.block,块是复合语句的别名。所以上面的规则完全是关于block的,它与范围无关。该规则相当于:
不得在受控语句的最外层复合语句中重新声明。
所以,我在这里无法理解的是,由于 inner 的条件switch
和 first 的最外层块之间没有任何块switch
,怎么能说 inner 的条件switch
不在 outer 的最外层块中switch
?
switch(int a = 1){ <- outermost block of the primary `switch`
case 1: switch(int a = 2 /*there's no any block contains this condition*/){}
}
作为对比:
switch(int a = 1){ <- outermost block of the primary `switch`
case 1: { /* here exists a block between `int a = 2` and outermost block of the primary `switch`, so the condition definitely not in the outermost block*/
switch(int a = 2 ){}
}
}
我错过的标准中是否有任何关于类似于stmt.while#2的转换的规则,这将使条件包含在发明的块(复合语句)中?
解决方案
真正的问题是这里的含义。{
和}
分隔之间的任何东西switch
当然都在那个“最外层块”中,但是“最外层”的使用清楚地暗示我们不应该考虑(也)在嵌套块内的程序部分。达到这种解释的最简单方法是将“in”读作“<strong>directly in”,这与“在命名空间中声明的函数”通常不包括该命名空间中的类的成员函数相同。然后嵌套的条件switch
被免除,因为其中的声明不直接在任何块中。
P1787R6于 2020 年 11 月通过,它通过重写 [basic.scope.block] 来明确指出与子语句相关的单数范围,与 [stmt.while]/2 中的转换无关。
推荐阅读
- python - 如何找到同一年所有分数的平均值(Python)
- android - 使用 android 导航 safeArgs 时的许多参数
- c# - asp.net core登录功能报错“并非所有代码路径都返回值”
- django - 如何更改 moziila_django_oidc 中的 redirect_uri?
- winapi - 在 .code 之外调用汇编函数
- javascript - 延迟加载 Wildfire 评论
- sql-server - 使用 Docker 映像还原 SQL Server 数据库,导致 SA 登录错误
- python - python multiprocessing:如何从子进程修改在主进程中创建的字典?
- javascript - 如何先从 Api 获取数据,然后调用 my 函数?
- reactjs - npm 错误!404 未找到 - 获取 https://registry.npmjs.org/creat-react-app - 未找到