c++ - ¿Qué es "rvalue reference for*this"?




c++11 move-semantics (2)

Digamos que tiene dos funciones en una clase, ambas con el mismo nombre y firma. Pero una de ellas es declarada const :

void SomeFunc() const;
void SomeFunc();

Si una instancia de clase no es const , la resolución de sobrecarga seleccionará preferentemente la versión no constante. Si la instancia es const , el usuario solo puede llamar a la versión const . Y this puntero es un puntero de const , por lo que la instancia no se puede cambiar.

Lo que hace "r-value reference for this` es permitirle agregar otra alternativa:

void RValueFunc() &&;

Esto le permite tener una función a la que solo se puede llamar si el usuario la llama a través de un valor-r adecuado. Así que si esto está en el tipo Object :

Object foo;
foo.RValueFunc(); //error: no `RValueFunc` version exists that takes `this` as l-value.
Object().RValueFunc(); //calls the non-const, && version.

De esta manera, puede especializar el comportamiento en función de si se accede al objeto a través de un valor r o no.

Tenga en cuenta que no puede sobrecargarse entre las versiones de referencia de valor r y las versiones que no son de referencia. Es decir, si tiene un nombre de función miembro, todas sus versiones usan los calificadores l / r-value en this , o ninguno de ellos lo hace. No puedes hacer esto:

void SomeFunc();
void SomeFunc() &&;

Tienes que hacer esto:

void SomeFunc() &;
void SomeFunc() &&;

Tenga en cuenta que esta declaración cambia el tipo de *this . Esto significa que las versiones && todos los miembros de acceso como referencias de valor r. Así que es posible moverse fácilmente desde dentro del objeto. El ejemplo dado en la primera versión de la propuesta es (nota: lo siguiente puede no ser correcto con la versión final de C ++ 11; es directamente de la propuesta inicial "r-value from this"):

class X {
   std::vector<char> data_;
public:
   // ...
   std::vector<char> const & data() const & { return data_; }
   std::vector<char> && data() && { return data_; }
};

X f();

// ...
X x;
std::vector<char> a = x.data(); // copy
std::vector<char> b = f().data(); // move

Encontré una propuesta llamada "rvalue reference for * this" en la página de estado de C ++ 11 de Clang.

He leído bastante acerca de las referencias de valores y las he entendido, pero no creo que sepa esto. Tampoco pude encontrar muchos recursos en la web usando los términos.

Hay un enlace al documento de propuesta en la página: N2439 (Extender la semántica de movimiento a * esto), pero tampoco recibo muchos ejemplos de eso.

¿De qué se trata esta característica?


Hay un caso de uso adicional para el formulario de calificador ref del calificador. C ++ 98 tiene un lenguaje que permite llamar a funciones miembro no const para instancias de clase que son valores. Esto conduce a todo tipo de rarezas que van en contra del concepto mismo de rvalidad y se desvía de cómo funcionan los tipos integrados:

struct S {
  S& operator ++(); 
  S* operator &(); 
};
S() = S();      // rvalue as a left-hand-side of assignment!
S& foo = ++S(); // oops, dangling reference
&S();           // taking address of rvalue...

Los ref-calificadores de Lvalue resuelven estos problemas:

struct S {
  S& operator ++() &;
  S* operator &() &;
  const S& operator =(const S&) &;
};

Ahora los operadores funcionan como los de los tipos incorporados, aceptando solo valores de l.





qualifiers