Bạn nên trả về giá trị.
Tiêu chuẩn có một tính năng cụ thể để cải thiện hiệu quả trả về theo giá trị. Nó được gọi là "sao chép elision", và cụ thể hơn trong trường hợp này là "tối ưu hóa giá trị trả về có tên (NRVO)".
Trình biên dịch không phải thực hiện nó, nhưng sau đó một lần nữa trình biên dịch không có để thực hiện chức năng nội tuyến (hoặc thực hiện bất kỳ tối ưu hóa nào cả). Nhưng hiệu suất của các thư viện chuẩn có thể khá kém nếu các trình biên dịch không tối ưu hóa, và tất cả các trình biên dịch nghiêm trọng đều thực hiện nội tuyến và NRVO (và các tối ưu hóa khác).
Khi NRVO được áp dụng, thì sẽ không có sao chép trong đoạn mã sau:
std::vector<int> f() {
std::vector<int> result;
... populate the vector ...
return result;
}
std::vector<int> myvec = f();
Nhưng người dùng có thể muốn làm điều này:
std::vector<int> myvec;
... some time later ...
myvec = f();
Sao chép sự bỏ bớt không ngăn cản một bản sao ở đây bởi vì đó là một bài tập thay vì khởi tạo. Tuy nhiên, bạn nên vẫn còn trả về theo giá trị. Trong C++ 11, nhiệm vụ được tối ưu hóa bởi một cái gì đó khác, được gọi là "di chuyển ngữ nghĩa". Trong C++ 03, đoạn mã trên không gây ra một bản sao, và mặc dù trong lý thuyết một trình tối ưu hóa có thể tránh được nó, trong thực tế nó quá khó. Vì vậy, thay vì myvec = f()
, trong C++ 03 bạn nên viết này:
std::vector<int> myvec;
... some time later ...
f().swap(myvec);
Có một tùy chọn, mà là để cung cấp một giao diện linh hoạt hơn cho người sử dụng:
template <typename OutputIterator> void f(OutputIterator it) {
... write elements to the iterator like this ...
*it++ = 0;
*it++ = 1;
}
Bạn có thể sau đó cũng hỗ trợ giao diện vector-based hiện trên đầu trang của rằng:
std::vector<int> f() {
std::vector<int> result;
f(std::back_inserter(result));
return result;
}
này thể thể ít hiệu quả hơn so với mã hiện tại của bạn, nếu mã hiện tại của bạn sử dụng reserve()
theo cách phức tạp hơn chỉ là một số tiền cố định ở phía trước. Nhưng nếu mã hiện tại của bạn về cơ bản gọi số push_back
trên vectơ nhiều lần, thì mã mẫu dựa trên mẫu này phải là tốt.
Làm cách nào để truyền véc-tơ bằng tham chiếu và sau đó điền vào bên trong 'f'? –
[RVO] (http://en.wikipedia.org/wiki/Return_value_optimization) là một tối ưu hóa khá cơ bản mà hầu hết các trình biên dịch sẽ có khả năng làm bất cứ lúc nào. –
Khi câu trả lời trôi chảy, nó có thể giúp bạn làm rõ liệu bạn đang sử dụng C++ 03 hoặc C++ 11. Các phương pháp hay nhất giữa hai phiên bản khác nhau khá nhiều. –