c++ - 访问由 C++ 中的局部声明隐藏的封闭范围(非全局)中的变量?
问题描述
范围解析运算符::
可用于访问被局部声明遮蔽的全局变量。对于在封闭范围中声明但不是全局的变量,您如何实现相同的效果?
int main() {
int i = 10;
if (1) {
int i = 5;
std::cout << "Local i: " << i << std::endl;
std::cout << "Main's i: " << ?? << std::endl; //How to access main's i?
}
return 0;
}
我知道这是不好的做法。但我只是想知道这是否可能。我认为不是。
解释为什么它不可能或它是如何有用的。
解决方案
不幸的是,这是不可能的。编译器警告选项,例如-Wshadow
GCC,可以帮助避免这种情况:
-W阴影
每当局部变量或类型声明遮蔽另一个变量、参数、类型、类成员(在 C++ 中)或实例变量(在 Objective-C 中)或内置函数被遮蔽时发出警告。请注意,在 C++ 中,如果局部变量隐藏了显式 typedef,编译器会发出警告,但如果它隐藏了 struct/class/enum,则不会发出警告。与 -Wshadow=global 相同。
例如,在您的示例中,您会收到如下警告:
:在函数“
int main()
”中::7:9: 错误:“
i
”的声明遮蔽了先前的本地 [-Werror=shadow]7 | int i = 5; |
正如@LF在下面的评论中指出的那样,您可以使用引用来访问另一个i
:
#include <iostream>
int main() {
int i = 10;
if (1) {
int& nonlocal_i = i; // just before shadowing
int i = 5;
std::cout << "Local i: " << i << std::endl;
std::cout << "Main's i: " << nonlocal_i << std::endl;
}
return 0;
}
但-Wshadow
仍然会抱怨,如果您要加倍努力寻找替代名称,您可以以i
不同的方式命名本地。
注意:
正如user4581301在评论中指出的那样,代码 likeint& i = i;
不会在内部范围内完成您所期望的:
#include <iostream>
int main()
{
int i = 4;
{
int& i = i;
std::cout << i;
}
}
它尝试使用变量i
来初始化自己。在 Microsoft 的编译器中,您会收到如下编译错误:
错误 C4700:使用了未初始化的局部变量“i”
在 GCC 中,如果您打开所有警告,您会收到以下消息:
错误:引用 'i' 用自身初始化 [-Werror=init-self]
但是如果你没有打开警告,它会默默地编译并做错事
推荐阅读
- javascript - 动态标签名称
- amazon-ec2 - 无法从 EC2 实例执行 sudo apt-get update
- python - 通过用户输入编辑字典 - Python
- php - 如何使用 3 天的间隔显示结束日期的数据?
- r - R中的线性回归中的Pr(> | t |)如何计算?
- node.js - 数据验证应该在请求级别还是在使用 expressjs 的中间件中完成?
- django - 如何使用 django rest api 和 websockets 构建实时物联网服务器?
- vue.js - 向 Vuetify 组件添加功能,大量传入 props
- coq - 为什么 coq 的类型检查器拒绝我的地图定义?
- javascript - 如何使用匿名函数在 Javascript 中仅使某些函数和变量全局可用?