为什么其中一些编译而一些不编译?
场景1:编译错误'main' : redefinition; previous definition was 'data variable'
#include <iostream>
using namespace std;
int main;
int main(){ }
场景2:编译错误syntax error : missing ';' before identifier 'obj
#include <iostream>
using namespace std;
class main { };
int main(){
main obj;
}
场景3:工作正常
#include <iostream>
using namespace std;
class main { };
int main(){
class main obj;
}
场景4:工作正常
#include <iostream>
using namespace std;
class main {};
main obj;
int main(){ }
答案 0 :(得分:8)
名称查找适用于名称。查找名称,与名称指定的名称无关。
在同一范围内,不允许将同一名称声明为函数和变量。
但是,即使class X
是函数或变量的名称,也允许X
存在。如果您有class X
,则当前范围将X
作为名称(指定该类)。如果同一作用域X
声明为类型名和变量名,则只需查找x
即可找到变量名。
如果新范围声明X
,那么在该范围内使用X
会在其范围内找到声明的名称,这称为 shadowing 。 (名称查找搜索当前范围,然后搜索包含该范围的范围,依此类推到全局范围。)
错误,尝试将main
声明为函数和变量
要处理main obj;
,请查找名称main
。首先检查当前作用域,找到函数名main
;所以它不会检查全局范围。我们说内部范围的名称 shadow 是外部范围的名称。因此,它与您从void foo(); foo obj;
class main
毫不含糊地说要查找班级名称main
;找不到int main()
所以它回退到检查全局范围。
没什么新内容,main obj;
没什么区别。
另一个有趣的例子是:
int x;
class x { };
int main()
{
x = 1; // ok
x y; // error, `x` means the int
class x y; // ok
}