GCC 中的奇怪行为:rvalue ref 和 lvalue ref 是协变返回类型

use*_*785 10 c++ gcc g++ language-lawyer

我有一小段代码:

struct Res { };

struct A {
    virtual Res &&foo();
};

struct B : A {
    Res &foo() override;
};
Run Code Online (Sandbox Code Playgroud)

它在 GCC 中编译,但不在 Clang 中编译:https : //godbolt.org/z/65rffW

根据此处引用的标准语言,左值引用不是右值引用的协变返回类型。

为什么 GCC 不报错?

ana*_*ciu 8

这实际上是一份标准缺陷报告的主题,一份相当古老的报告:

  1. 协变函数和左值/右值引用部分:11.7.3 [class.virtual] 状态:CD2 提交者:James Widman 日期:2009 年 9 月 1 日

[在 2010 年 3 月的会议上投票为 WP。]

11.7.3 [class.virtual] 第 5 段要求协变返回类型要么是指针要么都是引用,但它没有指定引用必须既是左值引用又是右值引用。据推测,这是一个疏忽。

提议的决议(2010 年 2 月):

将 11.7.3 [class.virtual] 第 5 段第 1 项更改如下:

...如果函数 D::f 覆盖函数 B::f,则如果函数满足以下条件,则函数的返回类型是协变的:

  • 两者都是类的指针,都是的左值引用,或者都是类的右值引用106

...

来自http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#960


代码无疑是格式错误的,Clang 和 MSVC(至少)确实解决了这个问题,而 GCC 没有。

我提交了一个错误报告:https : //gcc.gnu.org/bugzilla/show_bug.cgi?id=99664


更新:

该错误已修复,测试用例在这里。将包含在 gcc 12 中。