2011-08-23 4 views
7

Gần đây tôi đã chơi với các tham chiếu Rvalue và tôi đã gặp phải sự cố lạ. Hãy xác định một số lớp đơn giản tên là Foo có chứa một vector<int>:Sử dụng tham chiếu Rvalue trong danh sách khởi tạo

class Foo 
{ 
public: 

    Foo(std::vector<int>&& v) 
     : v_(v) 
    {} 

private: 

    std::vector<int> v_; 
}; 

Một ví dụ Foo thể được xây dựng bằng cách thông qua một vector<int> tạm thời như thế này:

std::vector<int> temp; 
Foo(std::move(temp)); 

Bây giờ, khi tôi đã cố gắng để bước qua mã này , Tôi nhận thấy rằng các vector bên trong Foo được xây dựng bằng cách sử dụng các bản sao-constructor thay vì di chuyển-constructor. Tuy nhiên, nếu tôi chỉ định các nhà xây dựng theo cách này thay vì:

Foo(std::vector<int>&& v) 
    : v_(std::move(v)) 
{} 

Sau đó, di chuyển-constructor của v_ thành viên là một cách thích hợp gọi. Tại sao vậy? Tại sao cần có std::move(v) dư thừa trong danh sách khởi tạo? Tại sao trình biên dịch không thể suy ra ý định gọi hàm di chuyển vector-constructor vì đối số constructor Foo tương ứng được xác định là tham chiếu Rvalue?

Nhân tiện, tôi đang sử dụng GCC 4.6 với tùy chọn -std = C++ 0x.

Cảm ơn sự giúp đỡ của bạn. PMJ

Trả lời

7

Bên trong hàm (hoặc hàm tạo) một tham số được đặt tên là một giá trị, ngay cả khi nó được khai báo là tham chiếu rvalue.

Lý do là cái gì đó như

void foo(std::vector<int>&& v) 
{ 
    bar(v); 
    baz(v); 
    boo(v); 
    buz(v); 
} 

Trong đó các cuộc gọi nên trình biên dịch xem xét di chuyển từ đối tượng v?

Không ai trong số họ, trừ khi bạn làm điều đó một cách rõ ràng.

+0

Vì vậy, bạn có thể nhận được cùng một hiệu ứng (mặc dù có thêm 1 lần gọi hàm khởi tạo) bằng cách đơn giản lấy đối tượng theo giá trị. Người gọi sử dụng 'std :: move', và hàm tạo sử dụng' std :: move'. 2 nhà xây dựng, nhưng không phân bổ. –

+0

@Bo Persson: Cảm ơn bạn câu trả lời rõ ràng. Tôi đã không nghĩ về vấn đề phát sinh từ việc tham chiếu đối số Rvalue nhiều lần. @ Nicol Bolas: Tôi không chắc tôi hiểu ý của bạn, bạn có thể cung cấp một số ví dụ không? Cảm ơn. – pmjobin