首页 > 解决方案 > 尾随返回类型不是类的完整类上下文是否有特定原因?

问题描述

请注意,[class.mem]p6中未提及尾随返回类型

一个类的完整类上下文是

(6.1) 函数体,
(6.2) 默认参数,
(6.3) noexcept-specifier ([except.spec]),
(6.4) 契约条件,或
(6.5) 默认成员初始化器

在类的成员规范内。[注意:嵌套类的完整类上下文也是任何封闭类的完整类上下文,如果嵌套类是在封闭类的成员规范中定义的。——尾注]

[expr.prim.this]p2对此也有注释:

如果声明声明了类 X 的成员函数或成员函数模板,则表达式 this 是可选 cv-qualifier-seq 和函数定义结尾之间的“指向 cv-qualifier-seq X 的指针”类型的纯右值、成员声明符或声明符。它不应出现在可选的 cv-qualifier-seq 之前,并且不应出现在静态成员函数的声明中(尽管其类型和值类别在静态成员函数中定义,因为它们在非静态成员函数中) . [注意:这是因为在知道完整的声明符之前不会发生声明匹配。— end note ] [ 注意:在尾随返回类型中,所定义的类不需要是完整的,以便类成员访问。稍后声明的类成员不可见。[ 例子: ...

标签: c++language-lawyer

解决方案


因为你不想要。

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

     auto baz() -> decltype(qux());
     auto qux() -> decltype(baz());
 }; 

现在您需要各种规则来解释上述哪些是允许的,哪些是不允许的。

那么为什么标准将noexcept-specifier放在完整类上下文中?难道它不允许在这样的代码中本质上相同的东西:

struct Test { 
    void foo() noexcept(noexcept(bar())); 
    void bar() noexcept(noexcept(foo())); 
};

?

标准似乎没有很好地解决这个问题,编译器对此的处理也有所不同。Clang 抱怨上面的代码,但吃了这个:

struct Test { 
    void foo() noexcept(Test::b);
    static const bool b = true;
};

GCC 也抱怨第二个代码,但接受交换了成员声明的代码。似乎它根本没有将 noexcept 说明符视为完整的类上下文。


推荐阅读