¿Qué significa el ampersand único después de la lista de parámetros de una statement de función miembro?

De la respuesta aquí .

class wrap { public: operator obj() const & { ... } //Copy from me. operator obj() && { ... } //Move from me. private: obj data_; }; 

Sé que && significa que el miembro se invocará cuando el objeto sea una referencia de valor real. Pero, ¿qué significa el ampersand único? ¿Cómo es diferente que sin el ampersand?

Significa que el miembro se invocará cuando el objeto sea una referencia lvalue.

[C++11: 9.3.1/5]: una función miembro no estática puede declararse con un calificador ref (8.3.5); ver 13.3.1.

[C++11: 13.3.1/4]: para las funciones miembro no estáticas, el tipo del parámetro de objeto implícito es

  • “Lvalue reference to cv X ” para las funciones declaradas sin un ref-qualifier o con el calificador & ref
  • “Referencia de rvalue a cv X ” para las funciones declaradas con el calificador && ref

donde X es la clase de la cual la función es miembro y cv es la calificación cv en la statement de la función miembro. [..]

(y algunas reglas más que no puedo encontrar)

Sin un calificador de ref , la función siempre se puede invocar, independientemente de la categoría de valor de la expresión a través de la cual la está invocando:

 struct foo { void bar() {} void bar1() & {} void bar2() && {} }; int main() { foo().bar(); // (always fine) foo().bar1(); // doesn't compile because bar1() requires an lvalue foo().bar2(); foo f; f.bar(); // (always fine) f.bar1(); f.bar2(); // doesn't compile because bar2() requires an rvalue } 

Demostración en vivo (gracias pretoriano)

Pero, ¿qué significa el ampersand único?

La función solo puede invocarse en un valor l, no en un valor r.

¿Cómo es diferente que sin el ampersand?

Sin un calificador de ref puede invocar la función en un lvalue o un valor de r.

Con un calificador de ref, solo puede llamar a la función en la categoría de valor correspondiente.

Se puede invocar una función sin un calificador de referencia para ambos valores rvalue y lvalues. Una función con un && ref-qualifier solo puede invocarse para rvalues. Una función con un calificador de & ref solo puede invocarse para lvalues.

 class No { void foo(); }; class L { void foo() &; }; class R { void foo() &&; }; No().foo(); // valid No no; no.foo(); // valid L().foo(); // invalid L l; l.foo(); // valid R().foo(); // valid R r; r.foo(); // invalid 

Desafortunadamente, solo puedo encontrar esta regla en 5.5 / 6, que se aplica solo a las expresiones de desreferencia de puntero a miembro. Sé que aplica lo contrario también.

Además, no puede sobrecargar al ref-calificador frente a ningún ref-calificador, consulte 13.1 / 2 punto 3. Puede sobrecargar en & vs && .

(Y debido a mi infructuosa búsqueda del estándar, la respuesta de LRiO ahora también contiene toda esa información).