我对§3.3.2/6中"第一"一词的解释是否正确?
Is my interpretation of the word 'first' in §3.3.2/6 correct?
在下面的片段中,我可以理解(从§3.3.2/6第二个要点)声明struct B* p;
中的名称B
作为类名注入全局命名空间。
struct A {
// struct B{};
int B;
struct B* p;
};
void f(B&) {}
int main()
{
A a;
f(*a.p);
}
§3.3.2/6:
类的声明点在详细的类型说明符如下所示:
对于形式的声明
类键属性说明符seqopt标识符;
标识符被声明为作用域中的类名包含声明,否则
对于形式的详细说明的类型说明符
类密钥标识符
如果在命名空间范围中定义的函数的decl说明符seq或参数声明子句中使用了详细说明的类型说明符,则标识符声明为包含声明的命名空间中的类名;否则,除了朋友声明外,标识符为在包含公告[注意:这些规则也适用于模板。--end注意][注意:其他形式的详细类型说明符不声明一个新名称,因此必须引用现有的类型名称。见3.4.4和7.1.6.3。——尾注]
然而,如果我在struct A
中取消注释struct B{};
的定义,那么我之前所说的关于将名称B
注入全局命名空间的内容将不再发生,因为代码不会编译。我认为这与上面的单词first(强调我的)有关,因为现在类名B
在声明struct B* p;
中不再是其声明区域中的第一个声明。我这么说对吗?
假设我的解释是正确的,为什么在这种情况下,类名B
没有注入全局命名空间?注意,在这种情况下,嵌套类struct B{};
将隐藏在A中,即,即使我们将函数f
的声明更改为void f(A::B&)
,代码也不会编译。
还有一点我不清楚:是什么让实现者决定在上面的第二个要点中,将类名注入到包含详细说明的类型说明符的命名空间或块范围中?也就是说,他们为什么不把类名声明留在类作用域内?
您是正确的,§3.3.2/6中的第一个关键字也是导致以下情况的原因:
struct A {
struct B *p;
struct B{};
int b;
};
void f(B* arg) {
std::cout << std::is_same<decltype(arg), A::B*>::value; // not the same type
}
int main()
{
A a;
f(a.p);
}
为什么在这种情况下,类名B没有被注入全局名称空间?
正如dyp所指出的,[basic.lookup.elab]/2解释了3.3.2只有在找不到以前的声明的情况下才执行
如果详细说明的类型说明符是由类键引入的,并且此查找找不到以前声明的类型名,或者如果详细的类型说明符出现在声明中,其形式为:
类密钥属性说明符seqopt标识符;
详细的类型说明符是一个声明,它引入3.3.2中描述的类名。
最后,我追踪到这种行为可能是C99 6.7.2.3/p8 的继承
如果形式的类型说明符
结构或联合标识符
发生除了作为上述表格的一部分,没有其他声明如果标识符作为标记可见,则它声明不完整结构或联合类型,并将标识符声明为113)
113)不存在具有enum的类似构造。
我认为你的解释是正确的。当您取消对struct B{};
的注释时,struct B* p;
行将简单地引用该结构体A::B
。
为了回答您的问题,当您将struct B {};
注释掉时,名称struct B
会插入全局范围。我想说的是,这是因为作者不希望您(在某种程度上)无声地将B
声明为A
的成员,而不使用成员规范作为名称B
。
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如果整数与指针大小相同,则重新解释将整数转换为指针双射是否具有双射作用?
- 任何人都可以解释一下我是否需要 & 在第一个代码片段中
- 是否可以解释为什么这会返回 21
- 是否有针对跳跃二进制搜索的直观解释
- 字符串中的空格是否会改变程序解释它的方式
- 程序读取文字或解释变量所需的时间是否更少
- 如何判断 std::vector 是否调整了自身大小,以及如何解释指向向量内值的指针不再有效
- 是否有任何方法可以在初始化之前更改变量的类型,您可以用示例解释
- 这种编译器优化不一致是否完全由未定义的行为来解释
- 重新解释cast<是否安全;bool*>清空内存
- 邪恶的字节块重新解释是否有效C++
- 编译器是否应该正确地将布尔中的任意非零值解释为true
- 我是否正确解释了Visual Studio程序集输出
- 我对§3.3.2/6中"第一"一词的解释是否正确?
- 像"T"这样的模板参数是否总是被解释为每个值?
- 在void*和void*之间进行强制转换时,混合使用静态强制转换和重新解释强制转换是否不安全?