es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Qué ha cambiado en C++17 en términos de elusión de movimientos?

¿Está garantizada la “elisión de movimiento” en C++17? Déjame explicarte a qué me refiero con esto. En casi todos los artículos sobre lo que se ha introducido en C++17, se puede encontrar el término: “elisión de copia garantizada para RVO”, que es bastante autoexplicativo. ¿Pero qué pasa con la construcción por movimiento?

Veamos el siguiente código, es simple: hay un tipo no copiable y dos funciones, una toma un parámetro NonCopyable por valor y la segunda lo toma por referencia de rvalue.

#include <iostream>

struct NonCopyable
{
  NonCopyable() = default;
  NonCopyable(const NonCopyable&) = delete;

  NonCopyable(NonCopyable&& other) noexcept
  {
    std::cout << "Move ctor\n";
  }
};

void func_by_value(NonCopyable cp)
{
  auto x = std::move(cp);
}

void func_by_rvalue_ref(NonCopyable&& cp)
{
  auto x = std::move(cp);
}

int main() 
{
  std::cout << "Pass by value:\n";
  func_by_value(NonCopyable());

  std::cout << "\nPass by rvalue_ref\n";
  func_by_rvalue_ref(NonCopyable());
}

Lo he compilado dos veces usando GCC(trunk) utilizando las siguientes banderas, y los resultados son ligeramente diferentes.

(1) -O0 -std=c++11 -fno-elide-constructors

Program output:
Pass by value:
Move ctor
Move ctor

Pass by rvalue_ref
Move ctor

(2) -O0 -std=c++17 -fno-elide-constructors

Program output:
Pass by value:
Move ctor

Pass by rvalue_ref
Move ctor

Así que mi pregunta es: ¿qué ha cambiado para que la construcción por movimiento se haya eliminado al usar C++17?
Explorador de compilador

Tags:  , ,

Answer

  1. Avatar for davy.ai

    En C++17, la “omisión de movimientos” también está garantizada junto con la “omisión de copia para RVO”. Esto significa que en ciertos casos, el compilador puede omitir la construcción de movimiento de un objeto. Esto puede ocurrir al mover un objeto temporal a un parámetro de función, como se muestra en el ejemplo de código proporcionado.

    En el caso de usar las banderas “-O0 -std=c++17 -fno-elide-constructors” al compilar el código, el constructor de movimiento no se omite, y tanto las funciones “Pasar por valor” como “Pasar por rvalue_ref” llaman al constructor de movimiento. Sin embargo, al usar solo las banderas “-O0 -std=c++17”, se omite el constructor de movimiento en la función “Pasar por valor”, lo que resulta en una sola llamada al constructor de movimiento en la salida del programa.

    Entonces, para resumir, la omisión del movimiento está garantizada en C++17, y el compilador puede omitir el constructor de movimiento en ciertos casos, lo que puede resultar en un código más eficiente.

Comments are closed.