在 C++ 中,我有一种情况,我想从内部块作用域访问在主函数的局部作用域中定义的变量。这是我的代码的简化版本:
#include <iostream>
using namespace std;
int var = 10; // Global variable
int main(int argc, char *argv[])
{
int var = 20; // Local variable in main
{
int var = 40; // Local variable in inner block
cout << ::var; // Prints 10 (the global variable)
// But I want to print the `var` in the `main` scope (20)
}
return 0;
}
我想让cout打印20,这是main范围内var的值。然而,使用 ::var 只给我全局变量值 10。
C++ 中是否有一种方法可以从该内部块中访问 main 中的局部变量(值 20),绕过内部块中定义的局部变量(值 40)?
我知道 C++ 没有相当于 Python 的 nonlocal 关键字,但是是否有一种解决方法或技术允许从封闭范围访问变量而不更改变量名称?
没有办法做到这一点。该语言没有提供区分
var
中的第一个 main
与第二个 var
的方法。
如果您曾经编写过生产代码,请避免使用此类变量。这将导致有错误的代码。您会对给定代码行中的范围内的变量感到困惑。
您无法访问其范围之外的变量(在某些情况下
extern
可以使用,但不能在您的代码中使用)。因此,您不能在其范围之外使用变量 var
(在最里面的块内声明)。例如,
int var = 10;
int main(int argc, char *argv[])
{
int var = 20; // this var
{
int var = 40;
}
cout << var; // this will access var declared first and prints 20
return 0;
}
相信我,不需要以这种方式声明和使用变量。这将导致有错误的代码。请记住,如果您使用 GCC 或 clang,请在编译时始终使用
-Wshadow
编译器标志,因为如果在代码中的任何位置执行类似的操作,它会显示警告。如果您不从终端编译代码,请尝试将其包含在您的 IDE 或 makefile 中。
案例A
int var = 10;
int main(int argc, char *argv[])
{
int var = 20; // this var
{
int var = 40;
cout << ::var; // This will output 10 because you have used scope of operator that'll point to global variable in C++.
}
return 0;
}
案例B
int var = 10;
int main(int argc, char *argv[])
{
int var = 20; // this var
{
int var = 40;
cout <<var; // This will output 40 because you are using local variable.
}
return 0;
}
案例C
int var = 10;
int main(int argc, char *argv[])
{
int var = 20; // this var
{
int var = 40;
}
cout << var; // this will output 20 because using var that is declared in main() function.
return 0;
}
关于您的示例代码
int var = 10;
int main(int argc, char *argv[])
{
int var = 20; // this var
{
int var = 40;
cout << ::var; // I want to print `var` variable in main scope.
// But this command print global variable.
}
return 0;
}
...以及评论中规定的目标,
” 我想在主作用域中打印
变量var
...您可以按如下方式执行此操作,只需为其添加 alias:
int var = 10;
int main()
{
int var = 20; // this var
{
auto& outer_var = var;
int var = 40;
cout << outer_var;
}
}
C++ 没有提供可以为您执行此操作的作用域解析机制。如果有这样一个机制,例如相对范围解析或函数名称作为伪名称空间名称,可能会被使用,然后人们会看到至少一些难以理解的代码,因为在一小段代码中对不同的事物使用相同的名称。另一种语言设计类似于 C#,其中隐藏(如内部
var
遮蔽外部 var
)是被完全禁止的。
同样,C++ 也没有提供任何方法来为全局命名空间提供额外的名称。其他命名空间可以使用别名,但全局命名空间不能使用别名,这样就可以非常确定全局命名空间不会通过类似
companyname::counter
的内容被引用。
C++ 还对名称空间作用域函数可以重载哪些运算符进行了限制,这也是为了提供一种绝对可以依赖的理智措施。关于最后一个基本原理,我从 Bjarne Stroustrup(语言创建者)那里得知。关于缺乏相对作用域解析和缺乏全局名称空间别名的基本原理,这只是一个合格的猜测,即它们是相同的,但这是有道理的。 :)