C++ 成员函数定义中的类型不完整

C++ 成员函数定义中的类型不完整,c++,language-lawyer,C++,Language Lawyer,国家: 函数定义的参数类型或返回类型在函数定义上下文中不得为不完整或抽象(可能为cv限定)类类型,除非函数被删除 并指出: 类在类说明符的结尾处被视为完全定义的对象类型(或完全类型)。类在其完整的类上下文中被认为是完整的;否则,在其自身的类成员规范中,它被视为不完整的 鉴于此代码: struct S { // S is incomplete S f() { /* S is complete in a function body */ return S(); } // S is in

国家:

函数定义的参数类型或返回类型在函数定义上下文中不得为不完整或抽象(可能为cv限定)类类型,除非函数被删除

并指出:

类在类说明符的结尾处被视为完全定义的对象类型(或完全类型)。类在其完整的类上下文中被认为是完整的;否则,在其自身的类成员规范中,它被视为不完整的

鉴于此代码:

struct S
{
  // S is incomplete
  S f() {  /* S is complete in a function body */ return S(); }
  // S is incomplete 
};
// S is complete

A不包括函数定义的decl说明符seq,也不包括函数的声明符,但是,每个编译器都说这是可以的。由于我找不到,什么措辞允许这样做?

引用链接的第一项:

类的完整类上下文是

  • 功能体([dcl.fct.def.general])

因此,在任何方法的函数体中,都被认为是一个完整的类上下文。据我所知,“函数定义的上下文”是函数体的同义词——与函数声明的上下文相反,函数声明的上下文不要求返回类型完整。

我认为编译器首先会找到标记
S
类(声明其所有成员)和
f
成员函数(仅包含声明,其中包括返回类型)。然后,对它们进行了分析

在分析
f
的函数体时,首先分析
S
类,并认为该类是完整的,因为它定义了成员函数(函数boby在那里,稍后将进行分析)

现在
S
已经完成,
f
可以使用
returns()


但另一种情况是:

struct S {
    decltype(S{}) f() { return S(); }
};

编译器希望通过
decltype
查找
S
的类型,以便考虑令牌(返回类型
f
),但由于
}而失败尚未到达类结尾。

我认为“类在其完整类上下文中被视为完整”的含义非常清楚。@NeilButterworth如果您查看完整类上下文的定义,则只包括函数体。@NeilButterworth但在函数定义中不包括,其中包含decl说明符seqAnd,在这个
S
中又是不完整的:)对我来说似乎是一个疏忽,
S
在返回类型中应该是不完整的,除非像您一样直接使用它。@KrystianS当前完整类上下文的定义已经很麻烦了,因为不清楚如何处理自引用的
noexcept
S。请参见和。否,函数定义的上下文是成员规范。此外,函数体不包括函数的返回类型或参数,请参见@krystian:这是函数声明的上下文,而不是函数定义…不,定义出现在成员规范中,因此,函数定义的上下文是成员规范,但定义本身只是主体——其余的是声明。不,声明可以是定义,如果提供了函数主体,请参阅。此外,根据您的解释,这将是格式良好的:虽然这样的措辞仍然不能使函数的返回类型或参数成为完整的类上下文。在“其他”情况下,如果您在关闭
}
后移动函数定义,则为gcc,因此这看起来像是一个gccbug@ChrisDodd我不这么认为。Gcc抱怨是因为我告诉你的原因,而不是因为函数的主体。