6

Digamos que tengo una función:¿Pasarán los valores de retorno por la referencia rvalue en C++ 0x?

typedef std::vector<int> VecType; 
VecType randomVector(); 

int processing() 
{ 
    VecType v = randomVector(); 
    return std::accumulate(v.begin(), v.end(), 0); 
} 

¿El C++ 0x dice específicamente la copia espuria se desvió desde el valor de retorno de randomVector? ¿O un compilador tendría que implementar el RVO? Me parece que el valor randomVector() debe tratarse como un valor r, y así debe llamarse al constructor de movimientos de v, pero no estoy completamente seguro de que esto sea cierto.

+0

No es una buena pregunta, en mi humilde opinión. El estándar no puede indicar de manera útil lo que PUEDE hacer una implementación, solo lo que DEBE hacer. –

+0

En realidad, en el ejemplo que le ha dado a Return Value Optimization, la mayoría de los compiladores lo realizan ... Por lo tanto, es efectivo sin valor r. También rvalue es más importante para pasar argumentos a las funciones. – Artyom

+0

El título de la pregunta es un poco engañoso. Su función devuelve un valor r y no una referencia. Pero una referencia rvalue puede vincularse a ella, que es lo que sucede en caso de que la elisión de copia no se pueda realizar por algún motivo y el tipo tenga un move-constructor (El parámetro move-constructor es una referencia rvalue) – sellibitze

Respuesta

7

La regla es la siguiente

  • Si el compilador puede hacer RVO, a continuación, se le permite hacerlo, y ninguna copia y se hizo ningún movimiento.
  • De lo contrario, se toma el constructor apropiado.

Como usted dice, lo temporal es un valor de lado derecho, y por lo tanto se selecciona el movimiento constructor, debido a una regla de 13.3.3.2/3, que dice que una referencia rvalue se une a un rvalue mejor que una referencia de valor izquierdo. Al decidir si usar el movimiento o el constructor de copia, la resolución de sobrecarga por eso preferirá el constructor de movimiento.

La regla de que el compilador puede realizar RVO está escrita en 12.8/15.

2

Todos los valores devueltos se consideran rvalues, por lo que si el compilador no implementa RVO en este caso, debe utilizar el constructor de movimientos en lugar del constructor de copias.

+1

No estoy seguro cómo interpretar el "debe usar el movimiento". AFAIU, asumió un compilador con soporte U/NRVO, el flujo de decisión es el siguiente: 1) si es compatible con RVO, optimice cualquier operación de movimiento/copia, 2) else si el movimiento construtor está disponible, úselo 3) else if copy constructor disponible, úselo 4) else programa mal formado – mloskot

+0

@mloskot Me refiero al constructor de movimientos seleccionado ya que es una mejor opción para la sobrecarga que el constructor de copias. – Motti

+2

Lo tengo. La suposición implícita de que exista el movimiento ctor no estaba claro para mí. Como move ctor está seleccionado, pero solo si existe. – mloskot

Cuestiones relacionadas