我在cppreference中看到了这一点。
在范围内查找名称会查找该名称的所有声明,只有一个例外,即“结构hack”或“类型/非类型隐藏”:在同一范围内,名称的某些出现可能引用了声明的
class/struct/union/enum
这不是一个typedef
,而具有相同名称的所有其它出现要么全部指代相同的变量,非静态数据成员(因为C ++ 14),或枚举,或者它们都指可能过载功能或功能模板名字
上面文本的链接在这里
我不明白什么是“结构破解”和“类型/非类型隐藏”。
他们是同一概念吗?你能给个简单的解释吗?进行摘要演示会很好。
该句子应真正理解为:
关于名称查找的例外涉及“结构hack”,也称为“类型/非类型隐藏”。
因此,您要寻找的概念的定义实际上是“类型/非类型隐藏”。
术语“ struct hack”可能令人困惑,因为它指的是C灵活数组,它是C特定的实现,而不是名称查找问题。
关于“类型/非类型隐藏”,它使您可以编写如下内容并进行编译:
#include <iostream>
namespace first
{
class vector
{
public:
int hidden;
};
}
namespace second {
using namespace first;
class vector
{
public:
int visible;
};
double f()
{
vector f;
f.visible=2;
int vector = f.visible;
return vector;
}
};
int main() {
std::cout << second::f() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,second::vector
隐藏first::vector
在的范围内namespace second
。
而且内部f
功能int vector
隐藏second::vector
。
这个概念在IBM线程中得到了很好的解释:
如果类名或枚举名在范围内且未隐藏,则可见。可以通过在嵌套的声明性区域或派生类中使用与对象,函数或枚举器相同的名称进行显式声明来隐藏类名称或枚举名称。在对象,函数或枚举器名称可见的任何位置,类名称或枚举名称都是隐藏的。此过程称为名称隐藏。
在成员函数定义中,本地名称的声明隐藏具有相同名称的类成员的声明。派生类中成员的声明隐藏了同名基类成员的声明。
您还可以检查iso cpp标准:
6.3.10名称隐藏[basic.scope.hiding]或http://eel.is/c++draft/basic.scope.hiding
一开始,有 C。在 C 中,像这样的声明是完全可能的(而且确实很频繁):
#include <time.h> // defines struct tm { ... }
struct tm tm;
int stat(const char *pathname, struct stat *statbuf); // defined somewhere in POSIX headers
Run Code Online (Sandbox Code Playgroud)
这段代码在 C 中是完全正常的,因为标签喜欢tm
或stat
不指定类型。只有struct tm
和struct stat
这样做。
#include <time.h>
tm my_time; // doesn't work in C
Run Code Online (Sandbox Code Playgroud)
输入 C++。在 C++ 中,如果您定义,struct tm { ... };
则tm
只有一个类型名称。
#include <time.h>
tm my_time; // OK in C++
Run Code Online (Sandbox Code Playgroud)
但是,如果没有引用中详述的“一个例外”,则上述 C 代码将无法使用 C++ 编译器进行编译。
#include <time.h>
struct tm tm; // would not compile without the exception
// because tm alone already refers to a type
// defined in this scope
Run Code Online (Sandbox Code Playgroud)
由于破坏完美的 C 代码不是 C++ 的意图,因此发明并实施了异常。它基本上是说你可以定义变量、函数和其他一些与 class/struct/union 标签同名的东西。如果你这样做了,那么标签本身就不再是这个范围内的类型名称。
#include <time.h>
struct tm tm; // compiles because of the exception
tm my_time; // no longer compiles because `tm` variable hides the type
struct tm my_time; // OK
Run Code Online (Sandbox Code Playgroud)
所以这就是“类型/非类型隐藏”(因为一个类型被一个非类型隐藏)” hack。它被称为hack是因为它在其他完全平滑和无聊的规则中略微弯曲(“每个名称都指一件事和一件事”),这允许一些(与旧的 C 代码的兼容性),如果没有的话,这是不可能的。正常的基于范围的名称隐藏不是黑客攻击。这是一个完全常规的事情,而不是巧妙的弯曲任何事物。
归档时间: |
|
查看次数: |
228 次 |
最近记录: |