Câu trả lời:
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
Điều này trả về một tham chiếu lơ lửng, giống như với trường hợp tham chiếu lvalue. Sau khi hàm trả về, đối tượng tạm thời sẽ bị hủy. Bạn nên trả về Beta_ab
theo giá trị, như sau
Beta_ab
Beta::toAB() const {
return Beta_ab(1, 1);
}
Bây giờ, nó chuyển đúng một Beta_ab
đối tượng tạm thời vào giá trị trả về của hàm. Nếu trình biên dịch có thể, nó sẽ tránh di chuyển hoàn toàn, bằng cách sử dụng RVO (tối ưu hóa giá trị trả về). Bây giờ, bạn có thể làm như sau
Beta_ab ab = others.toAB();
Và nó sẽ di chuyển xây dựng tạm thời vào ab
, hoặc làm RVO để bỏ qua việc di chuyển hoặc sao chép hoàn toàn. Tôi khuyên bạn nên đọc BoostCon09 Rvalue Reference Reference 101 để giải thích vấn đề và cách (N) RVO xảy ra để tương tác với điều này.
Trường hợp của bạn trả lại một tài liệu tham khảo giá trị sẽ là một ý tưởng tốt trong những dịp khác. Hãy tưởng tượng bạn có một getAB()
chức năng mà bạn thường gọi tạm thời. Nó không tối ưu để làm cho nó trả về một tham chiếu const lvalue cho các giá trị tạm thời. Bạn có thể thực hiện nó như thế này
struct Beta {
Beta_ab ab;
Beta_ab const& getAB() const& { return ab; }
Beta_ab && getAB() && { return move(ab); }
};
Lưu ý rằng move
trong trường hợp này không phải là tùy chọn, vì ab
không phải là tự động cục bộ cũng không phải là giá trị tạm thời. Bây giờ, trình phân loại giới thiệu &&
nói rằng hàm thứ hai được gọi trên các giá trị tạm thời, thực hiện bước di chuyển sau, thay vì sao chép
Beta_ab ab = Beta().getAB();
Nó có thể hiệu quả hơn, ví dụ, trong một bối cảnh hơi khác:
template <typename T>
T&& min_(T&& a, T &&b) {
return std::move(a < b? a: b);
}
int main() {
const std::string s = min_(std::string("A"), std::string("B"));
fprintf(stderr, "min: %s\n", s.c_str());
return 0;
}
Như một quan sát thú vị, trên máy của tôi clang++ -O3
tạo ra 54 hướng dẫn cho mã ở trên so với 62 hướng dẫn cho thường xuyên std::min
. Tuy nhiên, với -O0
nó tạo ra 518 hướng dẫn cho mã ở trên so với 480 cho thường xuyên std::min
.
for(:)
và tích hợp trên đối tượng bị hủy. Khắc phục: ideone.com/tQVOal
std::move()
chỉ được sử dụng như một diễn viên rõ ràng để minh họa điểm rõ ràng hơn. Đây không phải là mã bạn sẽ sao chép-dán vào dự án của bạn. Nó không mâu thuẫn với câu trả lời được bình chọn hàng đầu, bởi vì có đối tượng tạm thời được tạo bên trong hàm. Ở đây, đối tượng trả về là một trong các đối số (các đối tượng tạm thời bị hủy là bước cuối cùng trong việc đánh giá biểu thức đầy đủ (về mặt từ vựng) chứa điểm mà chúng được tạo).