【问题标题】:Incomplete types in member function definitions成员函数定义中的不完整类型
【发布时间】:2019-08-23 18:34:37
【问题描述】:

[dcl.fct.def] p2 状态:

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

[class.mem] p7 表示:

类在类说明符的结尾}处被视为完全定义的对象类型(或完整类型)。该类在其完整类上下文中被认为是完整的;否则在它自己的类member-specification中被认为是不完整的。

鉴于此代码:

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

A complete-class context 尤其不包括函数定义的 decl-specifier-seq ,也不包括函数的声明符,但是,每个编译器都说这是可以的。什么措辞允许这样做,因为我找不到它?

【问题讨论】:

  • 我认为“该类在其完整类上下文中被视为完整”的含义很清楚。
  • @NeilButterworth 如果您查看完整类上下文的定义eel.is/c++draft/class#mem-6,仅包含函数体。
  • @NeilButterworth 但在complete-class contexts 中不包括函数定义,它包含 decl-specifier-seq
  • 而在这个code snippet S 又是不完整的:) 对我来说似乎是一个疏忽,S 在返回类型中应该是不完整的,除非像你一样直接使用它。跨度>
  • @KrystianS 当前对完整类上下文的定义已经很麻烦了,因为不清楚如何处理自引用noexcepts。见stackoverflow.com/a/54767417/9585016CWG361

标签: c++ language-lawyer


【解决方案1】:

引用链接中的第一项:

一个类的完整类上下文是一个

  • 函数体([dcl.fct.def.general]),

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

【讨论】:

  • 不,函数定义的上下文是member-specification。此外,函数体不包括函数的返回类型或参数,见eel.is/c++draft/dcl.fct.def#general-1.sentence-2
  • @KrystianS:这是函数声明的上下文,而不是函数定义......
  • 不,定义出现在member-specification中,因此函数定义的上下文是member-specification
  • 但是定义本身只是主体——剩下的就是声明。
  • 不,声明可以是定义,如果提供了函数体,请参阅eel.is/c++draft/basic.def#2。此外,根据您的解释,这将是正确的:godbolt.org/z/L6TINp
【解决方案2】:

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

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

现在S已经完成,f可以使用return S()了。


但这是他的另一种情况:

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

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

【讨论】:

  • 该措辞仍然没有使函数的返回类型或参数成为完整的类上下文。
  • 在'other'的情况下,如果你在关闭}后移动函数定义,gcc still fails,所以这看起来像一个gcc错误
  • @ChrisDodd 我不这么认为。 Gcc 抱怨是因为我告诉的原因,而不是因为函数体。
猜你喜欢
  • 2021-07-25
  • 2016-01-10
  • 2015-09-04
  • 2019-09-25
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
  • 2016-05-27
  • 2016-10-26
相关资源
最近更新 更多