c++gccref-qualifier

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


The following code does not compile, expectedly:

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

My understanding is that the temporary A{} cannot bind to the &-qualified member function doWork, and this seems in line with this excerpt from cppreference (my italic):

[…] 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

Also clangd that I use in Vim tells me

'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]

However, when I compile with GCC, I get this error:

$ 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() & {
      |          ^~~~~~

which seems not as related to the error as the error from clangd.

On the other hand, I've read those two words, discards qualifiers, when erroneously calling a non-const member function on const object; in such a case I understand the use of "discards", as the object has a const that the function cannot honor, so it should be discarded for things to work.

However, this does not seems to be the case for the code above, where the problem is, I understand, the rvalue-ness of A{} as compared to the lvalue-ness that doWork() & expects.

Is the wording of the error from GCC wrong or am I misreading it?


Solution

  • This is just a case of a suboptimally worded error message in GCC.

    My guess would be that in GCC's implementation, diagnosing a mismatch between differing ref-qualifiers shares some code with diagnosing a mismatch between const and non-const, and they reused the same error message.

    I would encourage you to file a GCC bug suggesting an improvement to the error message.