2012-06-28 36 views
18

Người ta thường nói rằng trong C++ 11, bạn có thể trả về giá trị std::vector theo giá trị.Trả về tiêu chuẩn :: vectơ theo giá trị

Trong C++ 03, điều này phần lớn là đúng vì RVO nên tối ưu hóa bản sao. Nhưng rằng nên khiến hầu hết các nhà phát triển đều sợ hãi.

  • Trong C++ 11 sẽ được trả về std::vector biến cục bộ luôn được di chuyển?
  • Điều gì sẽ xảy ra nếu vector đó là thành viên của biến cục bộ thay vì biến cục bộ?
  • Rõ ràng trở về biến toàn cầu sẽ không được di chuyển. Những trường hợp nào khác sẽ không được di chuyển?
+0

Xem thêm [câu hỏi này] (http://stackoverflow.com/q/9532608/500104). – Xeo

Trả lời

15

Trước tiên, mỗi lần bản sao có thể được chọn lọc trước, nó vẫn có thể được ưu tiên ngay bây giờ và di chuyển có thể được ưu tiên trong cùng các trường hợp. Đối với phần còn lại của bài viết này, tôi sẽ giả định rằng sự cắt bỏ không xảy ra vì một lý do nào đó (giả vờ là người viết trình biên dịch lười biếng theo cách xấu).

Trong C++ 11 sẽ trả về tiêu chuẩn :: biến cục bộ vector luôn được di chuyển?

Mỗi khi tiêu chí sao chép bản sao được đáp ứng hoặc biến rõ ràng là std::move d.

Điều gì sẽ xảy ra nếu vector đó là thành viên của biến cục bộ thay vì biến cục bộ?

Nó sẽ không được di chuyển trừ khi rõ ràng std::move d.

Rõ ràng trở về biến toàn cục sẽ không bị di chuyển. Những trường hợp nào khác sẽ không được di chuyển?

Mỗi lần không đạt được tiêu chí sao chép bản sao và biến không rõ ràng std::move d.

Không ai trong số đó là lý do hợp lệ để không trả lại theo giá trị. Trả về bởi giá trị là ok, bởi vì ngay cả khi giá trị không được tự động di chuyển, bạn có thể ép nó bằng std::move.

+0

Tôi không nghĩ rằng nó sẽ được di chuyển nếu nó có thể là RVO'd. – juanchopanza

+0

@juanchopanza, vâng, không cái nào trong số này ngăn cản việc tối ưu hóa. –

+0

OK; điểm đầu tiên của bạn dường như ngụ ý rằng nó ** sẽ ** được di chuyển mỗi khi các tiêu chuẩn cho việc bỏ qua bản sao được đáp ứng. – juanchopanza

8

Trong C++ 11 sẽ được chuyển về std::vector biến cục bộ luôn được di chuyển?

Đối với một biến địa phương, thậm chí là một tham số theo giá trị, trình biên dịch phải luôn nỗ lực để di chuyển nó đầu tiên (nếu không phải di chuyển cũng không phải là bản sao có thể được elided vì lý do gì, ngay cả khi các tiêu chí là gặp). Nếu thất bại, nó cố gắng một lần nữa với một bản sao:

§12.8 [class.copy] p32

Khi các tiêu chuẩn cho sự bỏ bớt một hoạt động sao chép được đáp ứng hoặc sẽ được đáp ứng tiết kiệm cho một thực tế rằng các đối tượng nguồn là một tham số chức năng, và đối tượng cần sao chép được chỉ định bởi một giá trị lvalue, độ phân giải quá tải để chọn hàm tạo cho bản sao được thực hiện đầu tiên như thể đối tượng được chỉ định bởi giá trị.Nếu độ phân giải quá tải không thành công, hoặc nếu kiểu tham số đầu tiên của hàm tạo đã chọn không phải là tham chiếu rvalue đối với loại đối tượng (có thể cv đủ điều kiện), thì độ phân giải quá tải sẽ được thực hiện lại, xem xét đối tượng dưới dạng giá trị. [Lưu ý: Độ phân giải quá tải hai giai đoạn này phải được thực hiện bất kể việc quét bản sao có xảy ra hay không. Nó xác định constructor được gọi nếu không thực hiện elision, và constructor đã chọn phải được truy cập ngay cả khi cuộc gọi được elided. —thêm ghi chú]

Nếu vector đó là thành viên của biến cục bộ thay vì biến cục bộ thì sao?

Một dự án con sẽ không được cố gắng di chuyển vì không đáp ứng các tiêu chí để sao chép bản sao. (Mà là câm, IMHO, nhưng đó là cách nó hiện đang. Tôi không nghĩ rằng hai nên được liên kết, kể từ khi một subobject hoàn toàn có thể được di chuyển nếu đó là địa phương.)

Rõ ràng là trở về một biến toàn cầu sẽ không được di chuyển. Những trường hợp nào khác sẽ không được di chuyển?

Một tham chiếu rõ ràng sẽ không được di chuyển. Ngoài ra, tôi không thể nghĩ ra bất cứ điều gì khác.

+0

Điều gì về một tham chiếu đến một địa phương? Điều gì xảy ra nếu 'std :: move' được gọi trên ref nội bộ? –

+0

@deft_code: Bản thân tham chiếu sẽ không được chuyển tự động, có vẻ như câu cuối cùng của tôi không đủ rõ ràng về vấn đề đó. Tham chiếu 'std :: move''d sẽ di chuyển đối tượng được gọi đến. – Xeo

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