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



我有一小段代码:

struct Res { };
struct A {
virtual Res &&foo();
};
struct B : A {
Res &foo() override;
};

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

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

为什么GCC不发出错误?

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

  1. 协方差函数和左值/右值引用章节:11.7.3【虚拟课堂】状态:CD2提交人:James Widman日期:2009年9月1日

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

11.7.3[class.virtual]第5段要求协变返回类型既可以是指针也可以是引用,但没有规定引用必须是左值引用也可以是右值引用。大概这是一个疏忽。

拟议决议(2010年2月(:

将11.7.3[虚拟类别]第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中。

最新更新