C++ &引用;使用;类作用域的类型别名:[何时]方法中的用法可以在类型别名之前吗?

C++ &引用;使用;类作用域的类型别名:[何时]方法中的用法可以在类型别名之前吗?,c++,language-lawyer,type-alias,C++,Language Lawyer,Type Alias,昨天,我(愉快地)惊讶地发现,尽管别名的声明直到后来才出现在类定义中,但我能够编译出一个方法使用的代码 类型别名的这种“转发”用法有效吗?(我认为是这样,因为Clang5和GCC4.9都是这样工作的。) 什么规则涵盖了这种行为以及方法体和方法签名用法之间的差异 案例#1-使用在方法之后声明的、在方法体内部有效的方法(仅?) #包括 #包括 结构X{ std::string create(){//如果在签名中使用Y,则无法编译 返回Y{“hello!”};//当Y在这里时编译 } 使用Y=st

昨天,我(愉快地)惊讶地发现,尽管别名的声明直到后来才出现在类定义中,但我能够编译出一个方法使用的代码

  • 类型别名的这种“转发”用法有效吗?(我认为是这样,因为Clang5和GCC4.9都是这样工作的。)
  • 什么规则涵盖了这种行为以及方法体和方法签名用法之间的差异
案例#1-使用在方法之后声明的、在方法体内部有效的方法(仅?)

#包括
#包括
结构X{
std::string create(){//如果在签名中使用Y,则无法编译
返回Y{“hello!”};//当Y在这里时编译
}
使用Y=std::string;//在底部声明
};
int main()
{
std::cout这与。当您在成员函数体中时,该类被认为是完整的,并且可以使用该类中定义的任何内容,无论该类在类中的何处声明


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

我肯定在某些地方存在重复,但这是因为函数体是一个。注意:该术语仅在C++20中引入,但在此之前同样的概念也适用。
#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;
}
#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;
}