std :: move Vs std :: adelante

Esta parece ser la pregunta más relevante ya formulada.

¿Cuál es la diferencia entre std :: move y std :: forward

Pero cada respuesta es diferente y se aplica y dice cosas ligeramente diferentes. Entonces estoy confundido.

Tengo la siguiente situación.

Copiar artículo en contenedor
El elemento Copiar es C ++ 03, así que lo entiendo bastante bien.Construir artículo en contenedor
El elemento Construir en contenedor, creo, utiliza el reenvío perfecto correctamente para reenviar los argumentos a través de dos funciones al constructor de T enemplaceBackInternal() (Por favor diga lo contrario si me equivoco).Mover artículo al contenedor
Mi problema parece ser comprender cómo mover un artículo al contenedor.

El código:

template<typename T>
class Container
{
    std::size_t length;
    T*          buffer;

public:
    void push_back(T const& value)
    {
         resizeIfRequired();
         pushBackInternal(value);
    }
    template<typename... Args>
    void emplace_back(Args&&... args)
    {
         resizeIfRequired();
         emplaceBackInternal(std::forward<T>(arg)...);
    }
    void push_back(T&& value)
    {
         resizeIfRequired();
         // Is this forward correct or should it be move
         moveBackInternal(std::forward<T>(value));
    }
private:
    void pushBackInternal(T const& value)
    {
         // Copy construct object into buffer;
         new (buffer + length) T(value);
         ++length;
    }
    template<typename... Args)
    void emplaceBackInternal(Args&&... args)
    {
         // Construct object into buffer using arguments;
         new (buffer + length) T(std::forward<T>(args)...);
         ++length;
    }
    void moveBackInternal(T&& value)
    {
         // Move construct object into buffer;
         // Is this forward correct or should it be move
         new (buffer + length) T(std::forward<T>(value));
         ++length;
    }
};

Incluyo las tres aquí para comparar las tres funciones con las respuestas proporcionadas en la respuesta mencionada anteriormente. La razón principal es quemove yconstruct se ve tan similar que parece que deberían ser lo mismo.

Respondida @Potatoswatter Score 67

std :: forward tiene un solo caso de uso: para lanzar unparámetro de función con plantilla

Según esta definición, debería estar usandostd::move dentropush_back(T&& value) ymoveBackInternal(T&& value) ya que el valor no es un parámetro de plantilla para la función.

Respondida @Howard Hinnant Score 38

Si Y es una referencia de valor, el resultado será una expresión de valor.Si Y no es una referencia de valor, el resultado será un valor (xvalue para ser precisos) expresión.

Parece por esta definición que puedo usar cualquierastd::move ostd::forward.

Respondida @Bo Persson Score 11

std :: forward se usa para reenviar un parámetro exactamente como se pasó a una función.

Parece decir esostd::forward es aceptable (aunque si sigo el enlace en la respuesta todos los ejemplos usan funciones con plantilla).

Respuestas a la pregunta(1)

Su respuesta a la pregunta