【问题标题】:Where in the Standard (C++14) does it say that the following two declarations are equivalent?在标准 (C++14) 中哪里说以下两个声明是等价的?
【发布时间】:2015-06-24 16:39:17
【问题描述】:
struct A{};
int A;
struct A a;
struct A::A b;

上面的最后两个声明是等价的。它们都声明了 A 类型的对象。在标准中我可以在哪里找到或推断出这个?

【问题讨论】:

  • 我认为可能存在最后两个等价的情况......
  • 您是否在寻找第二个中使用的注入的类名的规范?或者 详细类型名称 struct A 明确指代类型而不是变量的规范?
  • @MooingDuck:确实,如果有一个命名空间A 包含一个不同的类A,那么第二个将表示这一点。
  • @Columbo:I disagree。您不能在与类相同的范围内声明命名空间,但可以使用 using 将其引入范围内。
  • @Columbo:适合 Clang。不幸的是,星期五太晚了,我不在乎哪个是正确的。

标签: c++ language-lawyer c++14


【解决方案1】:

[类]/2:

class-name 被插入到声明它的作用域中 在看到类名之后立即。 类名也是 插入到类本身的范围内;这被称为 注入的类名

A::A::A::A 也指 A。在某些情况下,A::A 可以改为命名构造函数,但 - [class.qual]/2 涵盖了这一点,其注释甚至针对您的示例:

在不忽略函数名称的查找中33nested-name-specifier 指定了一个类 C

  • 如果在 nested-name-specifier 之后指定的名称,当在 C 中查找时,是 injected-class-name C(第 9 条),或
  • 在作为 member-declarationusing-declaration (7.3.3) 中,如果在 nested-name- 之后指定的名称 specifier 与最后一个组件中的标识符或 simple-template-idtemplate-name 相同 嵌套名称说明符

该名称被认为是命名类 C 的构造函数。 [ 注意: 例如构造函数是不可接受的 查找结果为 详细类型说明符,因此构造函数 不会用于代替 injected-class-name — end 注意 ]


33) 忽略函数名的查找包括 出现在 nested-name-specifier 中的名称,一个 elaborated-type- 说明符,或基本说明符

所以在这样的声明中

A::A a;

在查找A::A不会忽略函数名称,因此代码格式错误,因为A::A 指的是构造函数。然而,在

struct B : A::A {};
struct A::A a;

一切都很好,因为在基本说明符和详细类型说明符中忽略了函数名称。

【讨论】:

  • 我知道这一段。但是您是如何从中推断出 A::A 等价于上述声明中的类型 A 的呢?
  • @Leon 那段话是这么说的。
  • @LeonTrotski:这是一个不会忽略函数名称的上下文。在这种情况下,它指的是构造函数(参见第 3.4.3.1 节)(and this question)。
  • @LeonTrotski 因为这是 A::A 命名构造函数的上下文之一 :)
  • @Columbo:太好了,谢谢!我刚刚发现A::A 应该在“nested-name-specifierelaborated-type-specifier 中引用类,而不是构造函数i>基本说明符。”例如:struct B : A::A {};(这里A::A指的是类,而不是构造函数)。你确实是对的!
最近更新 更多