static_cast reinterpret_cast references dynamic_cast cast c++ c++11 move static-cast

c++ - reinterpret_cast - ¿hay alguna diferencia entre la conversión estática a rvalue reference y std:: move



static_cast c++ definition (3)

Puede usar static_cast<A &&>(a) cuando a es un valor, pero no debe usar std::move(a) .
Cuando usa A && a = std::move(A()) , obtiene una referencia pendiente.

La idea básica es que la vida útil de un temporal no se puede extender aún más "pasándolo": una segunda referencia, inicializada a partir de la referencia a la cual se vinculó el temporal, no afecta su vida útil.

La implementación de std::move es algo así como

template <typename T> constexpr decltype(auto) move(T && __t) noexcept // when used in std::move(A()), // the lifetime of the temporary object is extended by __t { return static_cast<typename std::remove_reference<T>::type &&>(__t); // a xvalue returned, no lifetime extension } auto && a = std::move(A()); // the anonymous object wiil be destructed right after this line

La descripción para el reparto estático dice

Si new_type es un tipo de referencia rvalue, static_cast convierte el valor de expresión a xvalue. Este tipo de static_cast se usa para implementar la semántica de movimiento en std :: move. (Desde C ++ 11)

¿Esto confirma que los siguientes son equivalentes?

(UNA)

X x1; X x2 = static_cast<X&&>(x1);

(SEGUNDO)

X x1; X x2 = std::move(x1);


Sí, hay una diferencia muy importante: std::move documentos lo que quieres hacer. Además, el reparto es propenso a escribir errores como un tipo X olvidado o incorrecto.

Como se puede ver, std::move es aún menos que escribir.


T && En C ++ 11 es una referencia de valor. Se comportan como referencia de valor de C ++ 98,03. Su objetivo - ser un candidato para mudarse. En C ++ 98, tal construcción puede aparecer en refrie colapsando

std :: move - convierte la expresión en rvalue. Podría llamarse rvalue_cast , pero dicha palabra clave no existe.

Fundido explícito al tipo T && posible en principio. El estándar real cuesta algo de dinero, pero en el borrador de la norma ISO / IEC 14882: 2011 existe tal información

5.2.9 Reparto estático

8)

Las conversiones lvalue-to-rvalue (4.1), array-to-pointer (4.2) y function-to-pointer (4.3) se aplican al operando ...

Desde el punto de vista práctico, es más conveniente usar std :: move. Imagina tal ejemplo:

#include <stdio.h> #include <utility> class A { public: A () {printf ("A ()" "/n");} A (const A &) {printf ("A (&)" "/n");} A (A &&) {printf ("A (&&)" "/n");} A (const A &&) {printf ("A (const &&)" "/n");} ~ A () {printf ("~ A ()" "/n");} }; int main () { const A obj; A obj2 (std::move (obj)); // 1-st approach A obj3 (static_cast <const A&&> (obj)); // 2-nd approach }

En cuanto a mí, el primer enfoque es

  • más conveniente (¿debería realizar static_cast para const A && , o para A && ?)
  • más explícitamente (puedo usar la búsqueda en el editor de texto para encontrar std :: move in project)
  • menos propenso a errores cuando el desarrollador de software escribe código