C++ decltype与隐藏外部名称的类成员名称之间的交互

C++ decltype与隐藏外部名称的类成员名称之间的交互,c++,gcc,scope,language-lawyer,decltype,C++,Gcc,Scope,Language Lawyer,Decltype,此代码 int clash; struct Foo { decltype(clash) clash; }; 在clang上以静默方式编译,但在gcc上编译失败,并给出错误 错误:“int Foo::clash”[-fpermissive]的声明 错误:将“clash”的含义从“int clash”[-fpermissive]更改为“clash” 出现错误似乎需要两个要素: 阴影必须由类成员完成(如果是函数的局部作用域,则没有问题) 在声明[shadowing name]之前,必须在阴影作

此代码

int clash;

struct Foo {
  decltype(clash) clash;
};
在clang上以静默方式编译,但在gcc上编译失败,并给出错误

错误:“int Foo::clash”[-fpermissive]的声明

错误:将“clash”的含义从“int clash”[-fpermissive]更改为“clash”

出现错误似乎需要两个要素:

  • 阴影必须由类成员完成(如果是函数的局部作用域,则没有问题)

  • 在声明[shadowing name]之前,必须在阴影作用域中使用decltype([shadowed name])

  • 我的问题有两个:

  • gcc是否有理由拒绝该代码
  • 标准中哪里有这样的规定

  • gcc
    是正确的程序格式不正确,尽管此特定违规不需要诊断,因此
    clang
    不必提供诊断

    如果我们看一下C++11标准(最接近的草案是)部分
    3.3.7
    类范围,它说:

    类S中使用的名称N应在其名称中引用相同的声明 上下文以及在S.No.的完整范围内重新评估时 违反此规则需要进行诊断

    下一条规则是:

    如果对类中的成员声明进行重新排序,则会生成另一个有效的 (1)和(2)项下的程序,程序格式不正确,没有诊断 必需的

    我们希望避免在类中对声明进行重新排序时产生不同的程序,这是有道理的。令人好奇的是,他是否会这样做

    本节还提供了以下示例:

    enum { i = 1 };
    
    class X {
      char v[i]; // error: i refers to ::i
                 // but when reevaluated is X::i
      int f() { return sizeof(c); } // OK: X::c
      char c;
      enum { i = 2 };
    };
    
    如果我们用
    gcc
    ()尝试这个例子,我们会得到一个与您的代码产生的错误几乎相同的错误:

     error: declaration of 'i' [-fpermissive]
     enum { i = 2 };
              ^
    
     error: changes meaning of 'i' from '<anonymous enum> i' [-fpermissive]
     enum { i = 1 };
    
    错误:声明'i'[-fppermissive]
    枚举{i=2};
    ^
    错误:将“i”的含义从“i”[-fppermissive]更改为“i”
    枚举{i=1};
    
    gcc
    是正确的程序格式错误,尽管此特定违规不需要诊断,因此
    clang
    不必提供诊断

    如果我们看一下C++11标准(最接近的草案是)部分
    3.3.7
    类范围,它说:

    类S中使用的名称N应在其名称中引用相同的声明 上下文以及在S.No.的完整范围内重新评估时 违反此规则需要进行诊断

    下一条规则是:

    如果对类中的成员声明进行重新排序,则会生成另一个有效的 (1)和(2)项下的程序,程序格式不正确,没有诊断 必需的

    我们希望避免在类中对声明进行重新排序时产生不同的程序,这是有道理的。令人好奇的是,他是否会这样做

    本节还提供了以下示例:

    enum { i = 1 };
    
    class X {
      char v[i]; // error: i refers to ::i
                 // but when reevaluated is X::i
      int f() { return sizeof(c); } // OK: X::c
      char c;
      enum { i = 2 };
    };
    
    如果我们用
    gcc
    ()尝试这个例子,我们会得到一个与您的代码产生的错误几乎相同的错误:

     error: declaration of 'i' [-fpermissive]
     enum { i = 2 };
              ^
    
     error: changes meaning of 'i' from '<anonymous enum> i' [-fpermissive]
     enum { i = 1 };
    
    错误:声明'i'[-fppermissive]
    枚举{i=2};
    ^
    错误:将“i”的含义从“i”[-fppermissive]更改为“i”
    枚举{i=1};
    
    关于:
    int chash[sizeof(clash)]?不同的编译器会说什么?我想这与C++11投诉编译器无关,而是与它们在这种情况下的行为有关?不同的编译器会说什么?我想这与C++11投诉编译器无关,而是与它们在这种情况下的行为有关。我向你展示了如何引用实际标准,这是权威的。草案“意义不大”不是。。完全正确。它们的全部名称是“标准工作草案”,因此它们不仅仅是“草案”。你看,很明显,它们是逐渐完善的。你引用了一个草案,这意味着很少。我向你展示了如何引用实际标准,这是权威的。草案“意义不大”不是。。完全正确。它们的全部名称是“标准工作草案”,因此它们不仅仅是“草案”。从表面上看,很明显它们逐渐变得精致。