Closed brevzin closed 4 months ago
Actually probably need to move the "shall be a glvalue" wording to force temporary materialization conversion to some of the other cases in [expr.ref]/6. If we're accessing a data member or enumerator, need to do it. I'm not sure whether it's necessary for the overload resolution case for static member functions, so possibly in that sub-bullet as well?
CWG2813
Reference (section label): [expr.ref]
Issue description: [expr.ref]/2 currently starts:
This means that in
X().f()
, becauseX()
is a prvalue, the temporary materialization conversion is applied ([basic.lval]/7). Up until C++23, this detail wasn't significant since for any non-static member functionf()
,f()
's object parameter would have had reference type, so there was no other real alternative.But since C++23, with deducing this, we can now have non-static member functions that take their explicit object parameter by value. Which means that this example (from Johel Ernesto Guerrero Peña) is ill-formed:
X{}.f()
currently forces a temporary materialization conversion, which means that the explicit object parameterself
is initialized not from the prvalueX{}
(which would work) but rather from an xvalue, which does not.But taking a function pointer to
&X::f
and invoking it withX{}
would of course be fine. The more convenient direct member syntax should also be fine, and indeed P0847 contained motivating examples of using by-value member functions that take advantage of guaranteed copied elision.Suggested resolution:
Is the quoted sentence actually useful? For the existing non-static member function use-cases, because the object parameter already has reference type, the temporary materialization conversion will already be applied. It seems to simply force an undesired move construction in this case. The resolution might simply be: