#include <iostream>
int C;
class C {
private:
int i[2];
public:
static int f() {
return sizeof(C);
}
};
int f()
{
return sizeof(C); // why the C can't be the class type C.
}
int main()
{
std::cout << "C::f() = " <<C::f() << ","
<< " ::f() = " <<::f() << std::endl;
}
上述代码返回:C::f() = 8, ::f() = 4
我的问题是为什么全局函数C
中的标识符f
解析为具有名称C的类型int
的对象,而不是类型C
? sizeof
是否有特定的名称查找规则?
结论:从我在https://stackoverflow.com/a/612476/1021388中读到的内容,按函数/对象/枚举器名称隐藏类名是为了兼容性问题C.为了避免这种无意隐藏,应该typedef
强制编译错误的类。
答案 0 :(得分:20)
sizeof
不是这个问题的关键。它恰好是可以在类型名称或变量名称上使用的东西。这些规则也适用于标识符的其他用途。
§9.1[class.name](c ++标准草案n3797):
- ... snip ...如果在声明了同名变量,函数或枚举数的作用域中声明了类名,那么当两个声明都在作用域中时,该类只能被引用使用精心设计的说明符。
醇>
有一个名为C
的类和一个全局范围内同名的变量。因此,只能使用精心设计的类型说明符(class C
)来引用该类。
然而,在C
的定义中,该段的第一部分是相关的:
§9.1[class.name]:
- 类声明将类名引入声明它的范围,并在封闭范围内隐藏该名称的任何类,变量,函数或其他声明... snip ...
醇>
§9[class]:
- ... snip ...类名也插入到类本身的范围内;这被称为inject-class-name ... snip ...
醇>
因此,在class C
的范围内,注入的类名隐藏了外部作用域的int C
声明。因此,您可以参考C
而无需详细说明类型说明符。要引用全球int C
,您可以使用::C
答案 1 :(得分:3)
关于您的问题,sizeof
没有任何特殊的解析或评估规则。
请考虑以下事项:
#include <iostream>
#include <typeinfo>
int C;
class C {
public:
int i[2];
};
int main()
{
// compiles fine:
int x = C;
// prints 0:
std::cout << C << "\n";
// prints something that corresponds to "int"
// (or even "int" itself):
std::cout << typeid(C).name() << "\n";
}
在所有三种情况下,C
都被视为int
变量,而不是类型名称。
如果您需要明确区分,可以始终使用class C
:
#include <iostream>
#include <typeinfo>
int C;
class C {
public:
int i[2];
};
int main()
{
// prints something that corresponds to "class C"
// (or even "class C" itself):
std::cout << typeid(class C).name() << "\n";
// prints sizeof(int):
std::cout << sizeof(C) << "\n";
// prints sizeof(int) * 2:
std::cout << sizeof(class C) << "\n";
}
答案 2 :(得分:1)
尝试编译此代码将为您提供答案
-e DISPLAY
#include <iostream>
int C;
class C {
int i[2];
public:
static int f() {
return sizeof(C);
}
};
int f() {
return sizeof(C); // why the C can't be the class type C.
}
int main() {
C a; // <-- Adding this line generates the error
std::cout << "C::f() = " <<C::f() << ","
<< " ::f() = " <<f() << std::endl;
}
编译器:
prog.cpp:22:4: error: must use 'class' tag to refer to type 'C' in this scope
C a;
^
class
prog.cpp:3:5: note: class 'C' is hidden by a non-type declaration of 'C' here
int C;
^
1 error generated.
要获得正确的输出:
clang version 3.7.0 (tags/RELEASE_370/final 246979)
Target: x86_64-unknown-linux-gnu
Thread model: posix