繁体   English   中英

在另一个成员函数的尾随返回类型中获得推断成员函数的decltype是否格式良好?

[英]Is getting the decltype of a deduced member function inside the trailing return type of another member function well-formed?

无论谁说这个问题都是一个问题的重复“ 是否有一个特定的原因,为什么一个尾随返回类型不是一个完整的类的背景? ”并不知道他/她在说什么。 尾随返回类型不是类的完整类上下文的事实并不能解释为什么这个问题中的代码不能编译,尽管它解释了对另一个问题的答案中给出的代码的拒绝,特别是如OP所解释的,涉及成员函数quxbaz的代码的一部分。

为了澄清我的论点,即下面的代码是有效的,你必须考虑[expr.prim.this]中的第二个注释 ,它说: 在trailing-return-type中,被定义的类不需要是完成以便访问类成员。 稍后声明的类成员不可见。 由于foo在我的示例中在bar之前声明,因此没有什么可以阻止编译器在trailing-return-type bar访问foo

请注意@AathanOliver 下面的注释是基于下面的成员函数 foo的内联定义只是语法糖的猜想。 这需要从标准中的引用证明。 我还没有找到 一旦产生了这个引用,我肯定会接受一个答案,认为代码没有编译,因为trailing-return-type不是类的完整类上下文。

struct Test {
        auto foo() {}                       
        auto bar() -> decltype(foo()) {}
    };

prog.cc:3:32: error: use of 'auto Test::foo()' before deduction of 'auto'
    3 |     auto bar() -> decltype(foo()) {}
      |                                ^
prog.cc:3:32: error: use of 'auto Test::foo()' before deduction of 'auto'

[dcl.spec.auto] / 9

如果具有使用占位符类型的声明的返回类型的函数没有非丢弃的返回语句,则推断返回类型,就好像在函数体的右括号处没有操作数的return语句一样。 [例如:

auto f() { } // OK, return type is void

auto* g() { } // error, cannot deduce auto* from void()

- 结束例子]

[dcl.type.auto.deduct] /(2.1)

包含占位符类型的类型T和相应的初始化程序e确定如下:

(2.1)对于在使用包含占位符类型的返回类型声明的函数中发生的非废弃返回语句, T是声明的返回类型, e是return语句的操作数。 如果return语句没有操作数,则evoid() ;

(2.2)对于使用包含占位符类型的类型声明的变量,T是变量的声明类型,e是初始值设定项。 如果初始化是直接列表初始化,则初始化器应该是一个braced-init-list,只包含一个赋值表达式,e是赋值表达式;

(2.3)对于使用包含占位符类型的类型声明的非类型模板参数,T是非类型模板参数的声明类型,e是相应的模板参数。

根据[dcl.spec.auto] / 9和[dcl.type.auto.deduct] /(2.1),代码应该编译。 GCC和支持者拒绝了它。 我错过了什么?

 struct Test { auto foo() { /*1*/ } auto bar() -> decltype(foo()) {} }; 

在标记1处,名称Test::barstruct Test所有其他成员一起在范围内。 因此,在类完成之前,编译器无法分析foo()的主体。

然后我们有一个部分订购:

  • 在推断其返回类型之前,解析Test::foo()主体
  • 在解析Test::foo()主体之前完成类Test
  • 在完成类Test之前分析尾随返回类型的Test::bar() (从您提出的问题不是欺骗)

并且通过传递性,必须在不对Test::foo()执行返回类型推导的情况下分析Test::bar()返回类型。


由于要求标准报价,所以它来自[class.mem]

一类被认为是在闭合完全定义的对象类型(或完整的类型) }类指定符 在类成员规范中该类在函数体 ,默认参数, noexcept-specifiers和默认成员初始化器(包括嵌套类中的这类事物)中被视为完整 否则,它在其自己的类成员规范中被视为不完整。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM