用整数变量重载 class 名称
Overloading class name with integer variable
我正在使用列出的书籍学习 C++ here。特别是,我阅读了有关超载的信息。所以在阅读之后,我正在尝试不同的例子来进一步澄清我的概念。下面给出了一个我无法理解其输出的示例:
int Name = 0;
class Name
{
int x[2];
};
void func()
{
std::cout << sizeof(Name) << std::endl; //My question is: Why here Name refers to the integer variable Name and not class named Name
}
int main()
{
func();
}
当我调用 func
时,然后在语句 std::cout << sizeof(Name) << std::endl;
中,Name
指的是 int
Name
而不是 class 命名Name
。为什么会这样?我预计这会给我带来歧义错误,因为有两个(不同的)实体具有相同的名称。但是程序运行没有任何错误,sizeof
应用于 int Name
而不是 class 命名为 Name
。我在书中读过函数重载。但不是关于这种超载。它叫什么,这里发生了什么。
PS:我知道我可以写 std::cout<< sizeof(class Name);
,其中 sizeof
将应用于名为 Name
的 class 而不是变量 int Name
.此外,该示例用于学术目的。我知道应该避免使用全局变量。问题是不是关于如何解决这个问题(比如不为这两个实体使用相同的名称)而是关于正在发生的事情。
这里发生的是“阴影”。全局变量隐藏同名的 class。
您可以采取的措施是:
- (不要使用全局变量)
- 不要给不同的实体起相同的名字。通常变量和类型的命名约定是不同的(例如
name
代表变量 vs Name
代表类型)。
- 通过
std::cout << sizeof(class Name) << std::endl;
明确表示要引用该类型
- 如果您确实希望它们具有相同的名称,您可以将它们放在不同的命名空间中。
例如:
#include <iostream>
namespace foo {
int Name = 0;
}
namespace bar {
class Name {
int x[2];
};
}
namespace baz {
void func() {
std::cout << sizeof(foo::Name) << std::endl;
std::cout << sizeof(bar::Name) << std::endl;
}
}
int main()
{
baz::func();
}
PS:如评论中所述,这与重载无关。阴影通常是指具有相同名称的实体,但只能通过该名称访问一个实体。重载与此有很大不同,因为当您重载一个函数时,通常所有重载都是可访问的,并且重载决议决定使用哪一个。
自从您添加了 language-lawyer 标签:
当 class 和同名变量在同一范围内声明时,只要名称查找会找到它们,变量名称就会隐藏 class 名称,请参阅 [= post-C++20 标准草案的 18=]。 (请注意,在当前的 C++23 标准草案中,对名称查找的措辞进行了重大修改,但应该具有相同的效果。)
我认为选择这种行为是为了与 C 兼容,而不是在同一范围内同时声明 class 和同名变量是错误的。在 C 中,struct
s 与变量名位于不同的命名空间中,因此它们永远不会有歧义。例如
int Name = 0;
struct Name
{
int x[2];
};
在 C 中,只要你只写 Name
它就指代变量。如果您想引用类型,您 必须 使用 struct Name
。 C++ 消除了使用 struct
前缀来引用明确的 struct
的要求,但是按照它们的规则,Name
和 struct Name
的名称查找将具有在 C 和 C++ 中结果相同。
我正在使用列出的书籍学习 C++ here。特别是,我阅读了有关超载的信息。所以在阅读之后,我正在尝试不同的例子来进一步澄清我的概念。下面给出了一个我无法理解其输出的示例:
int Name = 0;
class Name
{
int x[2];
};
void func()
{
std::cout << sizeof(Name) << std::endl; //My question is: Why here Name refers to the integer variable Name and not class named Name
}
int main()
{
func();
}
当我调用 func
时,然后在语句 std::cout << sizeof(Name) << std::endl;
中,Name
指的是 int
Name
而不是 class 命名Name
。为什么会这样?我预计这会给我带来歧义错误,因为有两个(不同的)实体具有相同的名称。但是程序运行没有任何错误,sizeof
应用于 int Name
而不是 class 命名为 Name
。我在书中读过函数重载。但不是关于这种超载。它叫什么,这里发生了什么。
PS:我知道我可以写 std::cout<< sizeof(class Name);
,其中 sizeof
将应用于名为 Name
的 class 而不是变量 int Name
.此外,该示例用于学术目的。我知道应该避免使用全局变量。问题是不是关于如何解决这个问题(比如不为这两个实体使用相同的名称)而是关于正在发生的事情。
这里发生的是“阴影”。全局变量隐藏同名的 class。
您可以采取的措施是:
- (不要使用全局变量)
- 不要给不同的实体起相同的名字。通常变量和类型的命名约定是不同的(例如
name
代表变量 vsName
代表类型)。 - 通过
std::cout << sizeof(class Name) << std::endl;
明确表示要引用该类型
- 如果您确实希望它们具有相同的名称,您可以将它们放在不同的命名空间中。
例如:
#include <iostream>
namespace foo {
int Name = 0;
}
namespace bar {
class Name {
int x[2];
};
}
namespace baz {
void func() {
std::cout << sizeof(foo::Name) << std::endl;
std::cout << sizeof(bar::Name) << std::endl;
}
}
int main()
{
baz::func();
}
PS:如评论中所述,这与重载无关。阴影通常是指具有相同名称的实体,但只能通过该名称访问一个实体。重载与此有很大不同,因为当您重载一个函数时,通常所有重载都是可访问的,并且重载决议决定使用哪一个。
自从您添加了 language-lawyer 标签:
当 class 和同名变量在同一范围内声明时,只要名称查找会找到它们,变量名称就会隐藏 class 名称,请参阅 [= post-C++20 标准草案的 18=]。 (请注意,在当前的 C++23 标准草案中,对名称查找的措辞进行了重大修改,但应该具有相同的效果。)
我认为选择这种行为是为了与 C 兼容,而不是在同一范围内同时声明 class 和同名变量是错误的。在 C 中,struct
s 与变量名位于不同的命名空间中,因此它们永远不会有歧义。例如
int Name = 0;
struct Name
{
int x[2];
};
在 C 中,只要你只写 Name
它就指代变量。如果您想引用类型,您 必须 使用 struct Name
。 C++ 消除了使用 struct
前缀来引用明确的 struct
的要求,但是按照它们的规则,Name
和 struct Name
的名称查找将具有在 C 和 C++ 中结果相同。