“使用”类范围的类型别名:[何时] 方法中的用法可以先于类型别名吗?

use*_*740 3 c++ language-lawyer type-alias

昨天,当我能够编译具有使用 using 类型别名的方法的代码时,我(愉快地)感到惊讶,即使别名的声明直到类定义的后期才进行。

  • 类型别名的这种“转发”用法是否有效?(我认为是这样,因为 Clang 5 和 GCC 4.9 都是这样工作的。)
  • 哪些规则涵盖了这种行为以及方法主体和方法签名用法之间的区别?

案例 #1 - 使用方法后声明,在方法体内部有效(仅?)

#include <string>
#include <iostream>

struct X {
  std::string create() {     // fails to compile if Y used in signature
      return Y{"hello!"};    // compiles when Y here
  }

  using Y = std::string;     // declared at bottom
};

int main() 
{
    std::cout << X().create() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

案例 #2 - 上面声明的使用 [也] 在签名中有效

#include <string>
#include <iostream>

struct X {
  using Y = std::string;     // declared at top

  Y create() {               // can use Y here as well
      return Y{"hello!"};
  }
};

int main() 
{
    std::cout << X().create() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

Nat*_*ica 5

这与完整类上下文有关。当您在成员函数的主体中时,该类被认为是完整的,并且可以使用该类中定义的任何内容,无论它在类中的何处声明。

成员函数的返回类型不是完整类上下文的一部分,因此您只能使用代码中当时已知的名称。

  • 注意:该术语仅在 C++20 中引入,但在此之前也适用相同的概念。 (3认同)