根据我对 §3.4.1/8 的解释,这段代码应该可以编译。我错过了什么?

According to my interpretation of §3.4.1/8 this code should compile. What am I missing?

根据 [basic.lookup.unqual]/8 来自 N4140 the following snippet should compile. But it doesn't in clang、gcc 和 vs2013。

struct C {
    void f(I) {}
    using I = int;
};

[basic.lookup.unqual]/8(重点是我的):

For the members of a class X, a name used in a member function body, in a default argument, in an exception-specification, in the brace-or-equal-initializer of a non-static data member (9.2), or in the definition of a class member outside of the definition of X, following the member’s declarator-id31, shall be declared in one of the following ways:

  • before its use in the block in which it is used or in an enclosing block (6.3), or
  • shall be a member of class X or be a member of a base class of X (10.2), or
  • ...

31) That is, an unqualified name that occurs, for instance, in a type in the parameter-declaration-clause or in the exceptions-pecification.

[…] or in the definition of a class member outside of the definition of X, following the member’s declarator-id

即以下是有效的

struct C {
    using I = int;
    void f(I);
};

void C::f(I) {}

您的使用方式不符合[basic.lookup.unqual]/8中的任何条件,未使用:

  • 在成员函数体中
  • 在默认参数中
  • 在异常规范中
  • 在非静态数据成员的大括号或等于初始化器中

也不属于这种情况:

definition of a class member outside of the definition of X

以下示例显示了一些确实遵循这些规则的情况:

struct C {
    int y = I() ;           // brace-or-equal-initializer of non-static data member
    void f(int x = I())     // default argument
      noexcept(sizeof(I)<4) // exception-specification
    {
          I i = x ;         // member function body
    }
    using I = int;   
};