Pasando parámetros que necesitan ser copiados por valor o por referencia constante

7

Tengo una clase vectorial (matemática) básica, que en mi opinión se beneficia de la sobrecarga de operadores de C ++. Las operaciones escalares vectoriales se definen como funciones auto-modificables en la propia clase,

class Vec3i {
  Vec3i& operator+=(int const n) {
    for (int i = 0; i < 3; ++i) {
      _data[i] += n;
    }
  }
  std::array<int, 3> _data;
};

y como funciones libres no modificables. Para estos puedo ver dos opciones cuando se trata de pasar en el vector.

// By value, meaning an implicit copy.
Vec3i operator+(Vec3i lhs, int const rhs) {
  return (lhs += rhs);
}

// By const reference, copying manually.
Vec3i operator+(Vec3i const& lhs, int const rhs) {
  auto result = lhs;
  return (result += rhs);
}

¿Hay buenas razones para preferir una variante sobre la otra? Prefiero tener el parámetro const (que consiste en todo lo que nunca se modificará), pero la variante por valor es muy concisa. ¿O debería simplemente comenzar a leer el valor por valor como implícitamente const?

    
pregunta Kolja 15.12.2014 - 23:57

3 respuestas

5

En C ++ anterior (pre C ++ 11), no hay una diferencia significativa entre sus dos implementaciones de operator+ . O bien se llama al constructor de copia cuando invoca al operador o cuando realiza la copia explícita dentro del operador. En este caso, es más una cuestión de preferencia personal / directriz de codificación cuál elegir.

Con la introducción de constructores de movimientos en C ++ 11, el caso de paso por valor ha ganado una ventaja, ya que permite que el parámetro se construya utilizando el constructor de copia o el constructor de movimientos, dependiendo de lo que el operador está siendo invocado con.
Para su clase Vec3i , la diferencia no es tan grande, pero si tiene clases que mantienen recursos asignados dinámicamente, el uso adecuado de los constructores de movimientos puede reducir significativamente la cantidad de memoria que necesita su aplicación.

    
respondido por el Bart van Ingen Schenau 16.12.2014 - 10:07
2

Esto probablemente sea un poco de opinión, pero si veo dos alternativas equivalentes en el código, normalmente prefiero la que tiene menos "ruido". En su caso, la diferencia de la segunda alternativa a la primera es solo en "ruido" adicional: código técnico que no mejora la legibilidad de ninguna manera. Por eso preferiría la primera variante.

  

o simplemente debería comenzar a leer por valor como implícitamente const

Debería leer las funciones con argumentos "por valor" como libres de efectos secundarios, si eso es lo que quería decir.

    
respondido por el Doc Brown 16.12.2014 - 08:17
0

Iría por el enfoque de toma por valor.

Quizás en este caso no importa ya que Vec3i es barato de copiar, pero en general, esto permitiría que el valor de lhs se construya a partir de rvalue con un constructor de movimientos, eliminando así cualquier copia de objetos.

    
respondido por el UldisK 16.12.2014 - 09:36

Lea otras preguntas en las etiquetas