If one calls explicit object member function of a temporary, must the move of the temporary be elided in the explicit object parameter?
Consider the following example, where struct A
has move constructor deleted and f(this A)
is invoked for a temporary object A
:
struct A {
A() {}
A(A&&) = delete;
void f(this A) {}
};
int main() {
A{}.f();
}
The program is accepted in GCC, but both Clang and MSVC reject it:
call to deleted constructor of 'A'
error C2280: 'A::A(A &&)': attempting to reference a deleted function
Online demo: https://gcc.godbolt.org/z/rbv14cnz5
Which compiler is correct here?
This is CWG2813. As the issue description notes, the wording in C++23 requires a glvalue for the left operand of the dot operator, which implies that if the left operand is a prvalue, it must be converted to a glvalue first (materialized), which prevents copy/move elision. This outcome is undesirable; we would like to have the prvalue initialize the explicit object parameter directly. So, a change was made to the wording and it was approved as a DR. It will take compilers a while to catch up, but the intent is that the example should be accepted.