Pregunta

Yo había asumido que la forma canónica para el operador+, suponiendo la existencia de una sobrecarga del operador+= función miembro, era como este:

const T operator+(const T& lhs, const T& rhs)
{
    return T(lhs) +=rhs;
}

Pero se me señaló que esto también funcionaría:

const T operator+ (T lhs, const T& rhs)
{
    return lhs+=rhs;
}

En esencia, esta forma de transferencias de la creación de la temporal desde el cuerpo de la implementación de la llamada a la función.

Parece un poco incómodo tener diferentes tipos para los dos parámetros, pero hay algo mal con la segunda forma?Hay una razón para preferir uno sobre el otro?

¿Fue útil?

Solución

Con la edición de la pregunta, la primera forma sería preferido.El compilador es más probable que optimizar el valor de retorno (podría comprobar esto mediante la colocación de un punto de interrupción en el constructor de la T).La primera forma también toma dos parámetros como const, lo que sería más deseable.

La investigación sobre el tema de el valor de retorno de la optimización de la, como en este enlace como un ejemplo rápido: http://www.cs.cmu.edu/~gilpin/c++/performance.html

Otros consejos

No estoy seguro de si hay mucha diferencia en el código generado para cualquiera.

Entre estos dos, yo (personalmente) prefiere la primera forma, ya que mejor transmite la intención.Esto es con respecto tanto a su reutilización de el operador += y el lenguaje de pasar templatized tipos de const&.

Yo prefiero la primera forma para mejorar la legibilidad.

Tuve que pensar dos veces antes de ver que el primer parámetro ha de ser copiada.No me esperaba eso.Por lo tanto, ya que ambas versiones son probablemente igual de eficiente que se elija uno que es más fácil de leer.

const T operator+(const T& lhs, const T& rhs)
{
    return T(lhs)+=rhs;
}

¿por qué no si desea que el laconismo?

Mi primer pensamiento es que la segunda versión podría ser infinitessimally más rápido que la primera, porque no hay ninguna referencia se inserta en la pila como un argumento.Sin embargo, esto sería muy compilador que depende, y depende, por ejemplo si el compilador realiza Denominado Valor de Retorno de Optimización o no.

De todos modos, en caso de cualquier duda, nunca elija un muy pequeño aumento de rendimiento que incluso podría no existir y es más que probable que no necesitan, elige la más clara de la versión, que es la primera.

En realidad, la segunda es preferida.Como se indica en el estándar de c++,

3.7.2/2:Almacenamiento automático de duración

Si una llamada automática objeto tiene la inicialización o un destructor con efectos secundarios, no será destruido antes de que el final de su bloque, ni será eliminado como un optimización, incluso si parece ser no utilizados, a excepción de que un objeto de la clase o su reproducción puede ser eliminado como especificado en 12.8.

Que es, porque un anónimo temporal objeto es creado usando un constructor de copia, el compilador no puede utilizar el valor de retorno de la optimización.Para el segundo caso, sin embargo, el sin nombre, el valor de retorno de la optimización es permitido.Tenga en cuenta que si el compilador implementa denominada valor de retorno de la optimización, el mejor código es

const T operator+(const T& lhs, const T& rhs)
{
    T temp(lhs);
    temp +=rhs;
    return temp;
}

Creo que si alineadas a ambos (me gustaría ya que sólo están reenvío de funciones, y es de suponer que el operador+= (), la función está fuera de línea), se podría obtener cerca indistinguible de la generación de código.Dicho esto, la primera es la más canónica.La segunda versión es innecesariamente "lindo".

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top