2012-03-22 30 views
23

thể trùng lặp:
Returning unique_ptr from functionsTại sao tôi được phép sao chép unique_ptr?

20.7.1.2 [unique.ptr.single] định nghĩa constructor sao chép như thế này:

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

Vì vậy, tại sao các biên dịch đoạn mã sau khỏe?

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

tôi biên soạn nó như thế này:

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

Trình biên dịch: g ++ phiên bản 4.6.1 20.110.908 (Red Hat 4.6.1-9)

+18

+1 để thực sự cho chúng tôi biết bạn đang sử dụng trình biên dịch nào và cách bạn biên dịch mã. Một cảnh hiếm hoi trên StackOverflow. –

+0

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

Trả lời

42

Trong báo cáo trả về, nếu bạn trả về biến cục bộ, biểu thức được coi là giá trị và do đó tự động đã di chuyển. Do đó, nó tương tự như:

return std::move(p); 

Nó gọi hàm tạo unique_ptr(unique_ptr&&).

Trong chức năng chính, bar() tạo ra tạm thời, là một giá trị và cũng được di chuyển đúng cách vào p trong main.

+0

Không, subobjects không được tự động di chuyển. – Xeo

+0

12.8/31 có ví dụ chính xác như trong câu hỏi của tôi. Cả bạn và Nawaz đều đúng ngay –

+0

@ Xeo bạn nói đúng. Không có một câu hỏi về điều đó xung quanh? Có, có http: // stackoverflow.com/questions/9183087/will-member-subobjects-of-local-variables-được di chuyển-quá-nếu-trả-từ-a-functi –

1

Tôi nghĩ rằng sao chép từ một giá trị trái là bị vô hiệu hóa, nhưng "bar()" là một rvalue do đó, nó là OK. Bạn chắc chắn cần phải có thể sao chép từ giá trị.

+3

Và thực sự, đó là di chuyển từ rvalue, không sao chép. – ulidtko

13

Đó là khôngsao chép, nó là chuyển.

Lệnh return tương đương với điều này:

return std::move(p); 

nói vẻ thông thái, đó là ngữ nghĩa tương đương. Trong thực tế, trình biên dịch có thể tối ưu hóa mã, bỏ qua cuộc gọi đến hàm tạo-di chuyển. Nhưng điều đó chỉ có thể xảy ra nếu bạn viết như sau:

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

Đó là khuyến cáo. Tuy nhiên, trình biên dịch không có cơ hội để tối ưu hóa nếu bạn viết này:

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

Đó là không khuyến khích. :-)

Các vấn đề liên quan