在临时对象上调用左值引用限定成员函数时 GCC 错误消息的措辞

Wording of GCC's error message when calling lvalue-ref qualified member function on temporary object

预计以下代码无法编译:

struct A {
    void doWork() & {}
};
int main() {
    A{}.doWork();
}

我的理解是临时 A{} 不能绑定到 & 限定的成员函数 doWork,这似乎与 cppreference 的摘录一致(我的 斜体):

[…] member function of class X is treated as follows:

  • no ref-qualifier: the implicit object parameter has type lvalue reference to cv-qualified X and is additionally allowed to bind rvalue implied object argument
  • lvalue ref-qualifier: the implicit object parameter has type lvalue reference to cv-qualified X and is not allowed to bind rvalue implied object argument
  • rvalue ref-qualifier: the implicit object parameter has type rvalue reference to cv-qualified X

我在 Vim 中使用的 clangd 也告诉我

'this' argument to member function 'doWork' is an rvalue, but function has non-const lvalue ref-qualifier deleteme.cpp:2:10: note: 'doWork' declared here [member_function_call_bad_ref]

但是,当我用 GCC 编译时,我得到这个错误:

$ g++ -std=c++17 deleteme.cpp && ./a.out
deleteme.cpp: In function ‘int main()’:
deleteme.cpp:16:16: error: passing ‘A’ as ‘this’ argument discards qualifiers [-fpermissive]
   16 |     A{}.doWork();
      |                ^
deleteme.cpp:5:10: note:   in call to ‘void A::doWork() &’
    5 |     void doWork() & {
      |          ^~~~~~

这似乎不像 clangd 中的错误那样与错误相关。

另一方面,我读过这两个词,discards qualifiers,当错误地调用 non-const member function on const object;在这种情况下,我理解“丢弃”的用法,因为对象有一个函数无法接受的 const,所以应该丢弃它才能正常工作。

但是,上面的代码似乎并非如此,据我所知,问题在于 A{} 的右值与 [=25= 的左值相比] 预计。

GCC 错误的措辞有误还是我看错了?

这只是 GCC 中错误消息措辞不佳的一个例子。

我的猜测是,在 GCC 的实现中,诊断不同 ref-qualifiers 之间的不匹配与诊断 const 和 non-const 之间的不匹配共享一些代码,并且它们重复使用了相同的错误消息。

我鼓励您 file a GCC bug 建议改进错误消息。