2012-08-09 31 views
6

I push_back un objeto temporal en un vector como este,rvalue vector.push_back y copia-elisión

vector<A> vec; 
vec.push_back(A("abc")); 

se aplique el compilador copia-elisión para construir el temporal A("abc") directamente en el vector, de manera que A ' s copia ctor no se activará al insertar el objeto temporal en vec.

+0

No lo creo porque 'vector' (asignadores de STL en realidad) utiliza la ubicación' new'. –

+0

@Seth Carnegie: ¿cómo se relaciona con la colocación 'new'? digamos que tiene suficiente espacio libre en vector, entonces un compilador puede simplemente construir una instancia de 'A' en el lugar. –

+0

@Nya porque el compilador probablemente no sepa dónde se creará (no es que no pueda, pero no lo hará, porque los escritores del compilador no escribieron esa optimización). –

Respuesta

5

Si tiene un compilador que admita referencias rvalue, se moverá al vector, lo que a veces es bastante barato.

Una alternativa a eso es construir directamente el objeto en el vector, lo que se puede hacer con vec.emplace_back("abc");. Esto solo invoca un constructor.

Ambas son funciones de C++ 11. La elisión de copia no está permitida aquí, por lo que sin esas características la copia aún se realizará.

Sin embargo, si el constructor de copia no tiene efectos secundarios observables (que no debería tener de todos modos), un compilador inteligente aún puede realizar esa optimización, porque la regla "como-si" permite cualquier optimización que da como resultado mismo comportamiento observable. Sin embargo, no sé si algún compilador actual hace eso. De lo contrario, dudo que alguien gaste el esfuerzo de agregar tal optimización porque las referencias de valores ponen fin a esa necesidad.

+0

No estoy usando C++ 11 en este momento. – Alcott

+0

@Alcott, es probable que se realice una copia. –

+0

@ R.MartinhoFernandes o se llamará al operador de asignación; He visto ambos casos, y creo que depende de si se define un constructor de copia o si se define un operador de asignación para la clase (¿quizás los dos?). Otra razón por la cual "STL efectivo" es una lectura obligada para todos los desarrolladores de C++; Meyers habla sobre el uso de clases con los contenedores STL, y toca el por qué/cómo implementar las clases que se almacenarán en ellos. – Will

1

En el caso general, no se puede hacer, podría hacerse aquí ya que vector es una plantilla y el código puede estar en línea, dando más información al optimizador para hacer su trabajo y aliviando algunos de los requisitos de la función llamadas.

En el caso general, copiar elision funciona colocando los dos objetos sobre la misma ubicación en la memoria y teniendo solo dos nombres para referirse a un solo objeto. El problema en este caso sería que uno de los argumentos debe estar ubicado dentro del vector (asignado dinámicamente, en una posición particular), y el otro es un argumento para la función, que podría estar vinculado por la convención de llamada a una posición particular en la pila. Si ese es el caso, entonces el compilador no podrá optimizar la copia.

Cuestiones relacionadas