2010-09-15 33 views
22

Có thể trả lại một thùng chứa tiêu chuẩn từ một chức năng mà không cần sao chép không?Trả về C++ std :: vectơ không có bản sao?

Ví dụ mã:

std::vector<A> MyFunc(); 

... 

std::vector<A> b = MyFunc(); 

Theo như tôi hiểu, bản sao này giá trị trả về vào một vector mới b. Không làm cho hàm trả về tài liệu tham khảo hoặc một cái gì đó như thế cho phép tránh sao chép?

+0

Bản sao của http://stackoverflow.com/questions/3703302/c-vector-return-vs-parameter/3703325#3703325? –

Trả lời

25

Nếu trình biên dịch của bạn hỗ trợ NRVO thì sẽ không có bản sao nào được thực hiện, miễn là các điều kiện nhất định được đáp ứng trong hàm trả về đối tượng. Rất may, điều này cuối cùng đã được thêm vào trong Visual C++ 2005 (v8.0) Điều này có thể có tác động lớn đến sự hoàn hảo nếu container lớn, rõ ràng.

Nếu tài liệu trình biên dịch của bạn không cho biết có hỗ trợ hay không, bạn có thể biên dịch mã C++ thành trình lắp ráp (ở chế độ được tối ưu hóa/phát hành) và kiểm tra những gì được thực hiện bằng chức năng mẫu đơn giản.

Ngoài ra còn có một cuộc thảo luận rộng hơn xuất sắc here

+0

Cảm ơn! Bất kỳ ý tưởng về NRVO trong gcc? –

+0

@static_rtti - Tôi sẽ phải trì hoãn những người dùng Linux vì điều đó, vì sợ đặt chân vào miệng –

+0

Bạn có thể dễ dàng kiểm tra với một lớp học có dấu vết trong Sao chép CT. Lưu ý rằng đây là tối ưu hóa "có thể", điều đó không nhất thiết phải hoạt động, ví dụ: với các đối tượng trả về có tên khác nhau. Tuy nhiên, với các tham chiếu rvalue C++ 0x, các lớp có thể thực hiện một sự bảo đảm. Bạn có thể mong đợi điều này cho các thùng chứa tiêu chuẩn trong một STL cập nhật. – peterchen

2

Nếu bạn có thể thay đổi chữ ký của các chức năng sau đó bạn có thể sử dụng

std::vector<A>& MyFunc(); 

hoặc

void MyFunc(std::vector<A>& vect); 

Bạn cũng có thể trả về một con trỏ thông minh , nhưng điều đó liên quan đến việc làm mới đối tượng.

some_smart_pointer<std::vector<A>> MyFunc(); 

HTH

+4

Điều đầu tiên có thể sẽ không hoạt động nếu bạn trả về một vectơ là một địa phương trong hàm. Điều thứ hai là tốt mặc dù – jcoder

+3

@ John Burton/@ beezler - 'sẽ không hoạt động' là đặt nó nhẹ, giả sử container trả về là ngăn xếp dựa trên chức năng được gọi. –

13

Rvalues ​​("temporaries") liên kết với tài liệu tham khảo const sẽ có cuộc đời của họ kéo dài đến hết cuộc đời của tài liệu tham khảo. Vì vậy, nếu bạn không cần phải sửa đổi vector đó, sau đây sẽ làm:

const std::vector<A>& b = MyFunc(); 

nếu bạn cần phải sửa đổi các vector, chỉ cần mã hóa nó theo cách đó là dễ nhất để đọc cho đến khi bạn có bằng chứng (thu được qua profiling) rằng dòng này thậm chí còn quan trọng về hiệu suất.

Nếu không, hãy dựa vào C++ 1x với tham chiếu rvalue và di chuyển ngữ nghĩa sắp tới "thật sớm" và tối ưu hóa bản sao đó mà không cần phải làm gì cả.

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