2009-07-12 30 views

Trả lời

165
Beta_ab&& 
Beta::toAB() const { 
    return move(Beta_ab(1, 1)); 
} 

này trả về một tham chiếu lơ lửng, giống như với trường hợp tham khảo giá trị trái. Sau khi hàm trả về, đối tượng tạm thời sẽ bị hủy. Bạn nên trả lại Beta_ab theo giá trị, như sau

Beta_ab 
Beta::toAB() const { 
    return Beta_ab(1, 1); 
} 

Bây giờ, nó đúng cách di chuyển một đối tượng tạm thời Beta_ab vào giá trị trả về của hàm. Nếu trình biên dịch có thể, nó sẽ tránh được việc 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 làm một động thái hoặc sao chép hoàn toàn. Tôi khuyên bạn nên đọc BoostCon09 Rvalue References 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 bạn trả về tham chiếu giá trị sẽ là ý tưởng hay trong các trường hợp khác. Hãy tưởng tượng bạn có một hàm getAB() mà bạn thường gọi tạm thời. Nó không phải là tối ưu để làm cho nó trở về một tham chiếu const lvalue cho thời gian rvalue. 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 là không bắt buộc, vì ab không phải là một địa phương tự động hay một rvalue tạm thời. Bây giờ, ref-vòng loại&& nói rằng chức năng thứ hai được gọi vào temporaries rvalue, làm cho di chuyển sau, thay vì copy

Beta_ab ab = Beta().getAB(); 
+32

Tôi đã luôn luôn giả định các vấn đề tham khảo tòn ten ra đi automagically khi kiểu trả về là một tham chiếu giá trị r. Vui vì tôi nhận được điều đó ngay trước khi nó cắn tôi. Stack đập lỗi suck. –

+17

:) Thực sự, tham chiếu rvalue là "chỉ tham chiếu" như tham chiếu lvalue. họ không sao chép hoặc lưu trữ bất cứ điều gì. –

+0

Và ngay cả khi nó không elide các nhà xây dựng, trình biên dịch một cái gì đó biết nó có thể trả lại một rvalue-ref cho bạn tự động một cách an toàn. Ví dụ, theo các thí nghiệm của tôi, 'return x;' giống như 'return std :: move (x)'. (trong đó 'x' là biến cục bộ (tức là điểm này tôi đã thực hiện không trực tiếp áp dụng cho câu hỏi ban đầu về trả về tạm thời)). –

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