2012-03-22 13 views
23

Olası Çoğalt:
Returning unique_ptr from functionsNeden unique_ptr'yi kopyalayabilirim?

20.7.1.2 [unique.ptr.single] tanımlar böyle yapıcı kopyalayın: Yani

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

, neden aşağıdaki kod derleme yapar ince?

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

ben bunu böyle derlenmiş:

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

derleyici: g ++ sürüm 4.6.1 20110908 (Red Hat 4.6.1-9)

+18

+1. StackOverflow üzerinde nadir bir manzara. –

+0

Bkz. Http://stackoverflow.com/questions/4316727/returning-unique-ptr-from-functions – Sjoerd

cevap

42

İade beyanında, yerel bir değişken döndürürseniz, ifade bir değer olarak kabul edilir ve bu nedenle otomatik olarak , öğelerini taşır.

return std::move(p); 

Bu unique_ptr(unique_ptr&&) kurucu çağırır: nedenle benzer.

Ana işlevde, bar(), bir geçici değer üretir ve bu da bir rengin olur ve main içinde p'a doğru şekilde taşınır.

+0

Hayır, alt nesneler otomatik olarak taşınmaz. – Xeo

+0

12.8/31, sorumun tam örneğine sahiptir. Hem siz hem de Nawaz haklısınız –

+0

@Xeo haklısınız. Bu konuda bir soru yok muydu? Evet, http: // stackoverflow var.com/questions/9183087/will-member-subobjects-of-a-functi -onra-değiştirilmiş-de-if-return-from-a-functi –

1

Bir lvalue o kopyalama olduğunu düşünüyorum devre dışı, ancak "bar()" bir değerdir, bu yüzden sorun değil. Kesinlikle rıhtımlardan kopyalayabilmeniz gerekir.

+3

Ve aslında, kopyadan değil, rıhtımdan harekettir. – ulidtko

13

O değilkopyalanan, bu taşındı olduğunu olduğunu.

return ifadesinin bu eşdeğerdir:

return std::move(p); 

ukalalıkla konuşursak, bu semantik eşdeğer olduğunu. Gerçekte, derleyici kodu hareketlendirerek, çağrı yapıcıya yapılan çağrıyı seçebilir. Ancak bu, yalnızca şu şekilde yazılırsa mümkündür: Bu,

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

Bu önerilir. değil olduğunu

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

tavsiye: Bu yazarsanız Ancak derleyici optimize olanağının bulunmadığı. Bize hangi derleyiciyi kullandığınızı ve kodu nasıl derlediğinizi anlatmak için :-)

İlgili konular