【问题标题】:Injected class name compiler discrepancy注入的类名编译器差异
【发布时间】:2015-11-07 11:27:10
【问题描述】:

考虑这段代码:

struct foo{};

int main() {
    foo::foo a;
}

我希望这是格式正确的,按照 [class]/2(N4140,强调我的)中的规则声明 foo 类型的变量:

class-name 被插入到在看到 class-name 之后立即声明它的范围内。 类名也被插入到类本身的作用域中;这被称为 injected-class-name。 出于访问检查的目的,注入的类名被视为公共成员名。

clang 3.6.0 同意我的看法,编译上面的代码没有适用的警告-Wall -pedantic

gcc 5.2.0 不同意,提供以下错误消息:

main.cpp: In function 'int main()':
main.cpp:5:5: error: 'foo::foo' names the constructor, not the type
   foo::foo a;

无论注入的类名的嵌套有多深,上述内容都成立,例如foo::foo::foo::foo.

是否有规则强制该构造在该上下文中被解释为构造函数,或者这是一个gcc 错误?还是我对标准引用的解释有误?

【问题讨论】:

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


【解决方案1】:

在这种情况下,clang 似乎是错误的。我正在寻找的相关异常在 [class.qual]/2 中:

2 在不忽略函数名称且嵌套名称说明符指定类 C 的查找中:

  • (2.1) 如果在嵌套名称说明符之后指定的名称,在 C 中查找时,是 C 的注入类名称,或

  • [...]

该名称被认为是命名类 C 的构造函数。

该标准有一个近似等效的(显然是非规范性的)示例:

struct A { A(); };
struct B: public A { B(); };

A::A() { }
B::B() { }

B::A ba;// object of type A
A::A a;// error, A::A is not a type name
struct A::A a2;// object of type A

但是,clang 在这种情况下实际上会发出正确的诊断:

error: qualified reference to 'A' is a constructor name rather than a type wherever a constructor can be declared

也许clangIn a lookup in which function names are not ignored 行解释为In a lookup in which a constructor declaration is valid,但这似乎不是正确的解释。

clang bugzilla 中有一个existing bug

【讨论】:

【解决方案2】:

相关,但不是答案:GCC 人员完全讨论了这个for years 并认为它不应该被接受。他们在 GCC 4.5 和更新版本中明确将此作为错误 - 在 4.4.7 中已被接受。

顺便说一句:在调查此类内容时,您可能希望使用 Clang 的 -Weverything 而不是 -Wall -pedantic

【讨论】:

    【解决方案3】:

    我认为这是language defect #147的主题 其中包含这个例子

    class B { };
    class A: public B {
        A::B ab;       // B is the inherited injected B
        A::A aa;       // Error: A::A is the constructor
    };
    

    至少 gcc 似乎相信这一点。 :-)

    【讨论】:

    • 啊,所以相关的例外是 [class.qual]/2.2 这实际上是clang 中的一个错误?
    • 我不确定。此示例在类中使用 A::A,而您的使用在 main 中。那里可能有不同的规则。 (我只是对规则已更改的记忆很差,并查看了缺陷报告。
    猜你喜欢
    • 1970-01-01
    • 2017-07-26
    • 2014-09-01
    • 2015-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    相关资源
    最近更新 更多