2012-03-22 8 views
23

Eventuali duplicati:
Returning unique_ptr from functionsPerché sono autorizzato a copiare unique_ptr?

20.7.1.2 [unique.ptr.single] definisce costruttore di copia in questo modo:

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

così, perché i seguenti compila codice bene?

#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; 
} 

ho compilato in questo modo:

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

Il compilatore: g ++ versione 4.6.1 20.110.908 (Red Hat 4.6.1-9)

+18

+1 per dirci effettivamente quale compilatore stai utilizzando e come hai compilato il codice. Una vista rara su StackOverflow. –

+0

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

risposta

42

Nell'istruzione return, se si restituisce una variabile locale, l'espressione viene considerata come un valore rvalore, e quindi automaticamente spostato. È pertanto simile a:

return std::move(p); 

esso invoca il costruttore unique_ptr(unique_ptr&&).

Nella funzione principale, bar() produce un valore temporaneo, che è un valore di rvalore, e viene inoltre correttamente spostato nelloin main.

+0

No, i sottoggetti non vengono spostati automaticamente. – Xeo

+0

12.8/31 ha l'esatto esempio come nella mia domanda. Sia tu che Nawaz avete ragione. –

+0

@Xeo avete ragione. Non c'era una domanda a riguardo? Sì, c'è http: // StackOverflow.it/questions/9183087/will-member-subobjects-of-local-variables-be-moved-too-if-return-from-a-functi –

1

penso che la copia da un lvalue è disabilitato, ma "bar()" è un rvalore quindi va bene. Devi sicuramente essere in grado di copiare da rvalues.

+3

E in realtà, è il passaggio da rvalue, non da copia. – ulidtko

13

E 'noncopiato, è spostato.

L'istruzione return è equivalente a questo:

return std::move(p); 

pedantemente parlando, cioè semanticamente equivalente. In realtà, il compilatore può ottimizzare il codice, eliminando la chiamata al costruttore di movimento. Ma ciò è possibile solo se lo scrivi come:

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

Questo è raccomandato. Tuttavia, il compilatore non ha alcuna possibilità di ottimizzare se si scrive questo:

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

Questo è non raccomandato. :-)

Problemi correlati