2012-03-22 7 views
23

Duplicar posible:
Returning unique_ptr from functions¿Por qué puedo copiar unique_ptr?

20.7.1.2 [unique.ptr.single] define constructor de copia así:

// disable copy from lvalue 
unique_ptr(const unique_ptr&) = delete; 
unique_ptr& operator=(const unique_ptr&) = delete; 

Así que, ¿por qué las siguientes compila el código ¿multa?

#include <memory> 
#include <iostream> 

std::unique_ptr<int> bar() 
{ 
    std::unique_ptr<int> p(new int(4)); 
    return p; 
} 

int main() 
{ 
    auto p = bar(); 

    std::cout<<*p<<std::endl; 
} 

Compilé así:

g++ -O3 -Wall -Wextra -pedantic -std=c++0x kel.cpp 

El compilador: g ++ versión 4.6.1 20110908 (Red Hat 4.6.1-9)

+18

+1 por decirnos realmente qué compilador está utilizando y cómo compiló el código. Una vista rara en StackOverflow. –

+0

Ver http://stackoverflow.com/questions/4316727/returning-unique-ptr-from-functions – Sjoerd

Respuesta

42

En la declaración de devolución, si devuelve una variable local, la expresión se trata como un valor r, y por lo tanto automáticamente se movió. Por tanto, es similar a:

return std::move(p); 

se invoca el constructor unique_ptr(unique_ptr&&).

En la función principal, bar() produce un valor temporal, que es un valor r, y también se mueve correctamente al p en main.

+0

No, los subobjetos no se mueven automáticamente. – Xeo

+0

12.8/31 tiene el ejemplo exacto como en mi pregunta. Tanto tú como Nawaz tienen razón –

+0

@Xeo, tienes razón. ¿No había una pregunta sobre eso? Sí, hay http: // stackoverflow.com/questions/9183087/will-member-subobjects-of-local-variables-be-moved-too-if-returned-from-a-functi –

1

creo que la copia de un valor-I es desactivado, pero "bar()" es un valor r así que está bien. Definitivamente necesita poder copiar desde valores.

+3

Y en realidad, es el movimiento de rvalue, no copy. – ulidtko

13

Es no copiado, es trasladó.

La instrucción de retorno es equivalente a esto:

return std::move(p); 

pedante hablando, es decir semánticamente equivalentes. En realidad, el compilador puede optimizar el código, eludiendo la llamada al move-constructor. Pero eso solo es posible si lo escribe como:

return p; //It gives the compiler an opportunity to optimize this. 

Eso se recomienda. Sin embargo, el compilador no tiene ninguna oportunidad de optimizar si se escribe esto:

return std::move(p); //No (or less) opportunity to optimize this. 

Eso es no recomendado. :-)

Cuestiones relacionadas