2012-06-21 49 views
11

Tại sao định nghĩa của std :: chức năng <> :: operator() trong tiêu chuẩn C++ như sau:C++ 11 std :: chức năng và chuyển tiếp hoàn hảo

R operator()(ArgTypes...) const; 

và không

R operator()(ArgTypes&&...) const; 

?

Bạn có thể nghĩ rằng để chuyển tiếp thông số chính xác, chúng tôi cần & & và sau đó sử dụng std::forward<ArgTypes>... trong phần chức năng khi chuyển tiếp cuộc gọi?

tôi một phần reimplemented std :: chức năng để kiểm tra điều này và tôi phát hiện ra rằng nếu tôi sử dụng & &, tôi nhận được "không thể ràng buộc 'xxx' vế trái để 'xxx & &" từ g ++ khi tôi cố gắng sau đó để vượt qua thông số theo giá trị cho toán tử(). Tôi nghĩ rằng tôi đã nắm bắt đủ các khái niệm rvalue/forwarding, nhưng tôi vẫn không thể mò mẫm điểm này. Tôi đang thiếu gì?

Trả lời

13

Chuyển tiếp hoàn hảo chỉ hoạt động khi chính hàm đó (trong trường hợp này là operator()) được tô điểm và các đối số mẫu được suy luận. Đối với std::function, bạn nhận được các loại đối số operator() từ tham số mẫu của chính lớp , có nghĩa là chúng sẽ không bao giờ được suy luận từ bất kỳ đối số nào.

Toàn bộ thủ thuật đằng sau chuyển tiếp hoàn hảo là phần khấu trừ đối số mẫu, trong đó, cùng với việc thu gọn tham chiếu, là chuyển tiếp hoàn hảo là gì.

Tôi sẽ chỉ liên kết thuận tiện với my other answer about std::forward tại đây, nơi tôi giải thích cách chuyển tiếp hoàn hảo (và std::forward) hoạt động.

Lưu ý rằng operator() của không cần chuyển tiếp hoàn hảo, vì bản thân người dùng sẽ quyết định thông số nên là gì. Đây cũng là lý do tại sao bạn không thể chỉ thêm && đến operator(); lấy ví dụ này:

void foo(int){} 

int main(){ 
    // assume 'std::function' uses 'ArgTypes&&...' in 'operator()' 
    std::function<void(int)> f(foo); 
    // 'f's 'operator()' will be instantiated as 
    // 'void operator()(int&&)' 
    // which will only accept rvalues 
    int i = 5; 
    f(i); // error 
    f(5); // OK, '5' is an rvalue 
} 
+0

Cảm ơn, mọi thứ đã có ý nghĩa hoàn hảo ngay bây giờ. – airman

+0

@Xeo, mã của bạn biên dịch chính xác ... http://ideone.com/7TyCB8 Không có lỗi tại f (i), bạn có thể giải thích ý của bạn bằng "// error" hay có lẽ tôi đang sử dụng trình biên dịch sai. Cảm ơn. –

+0

@WillBradley: Đọc lại chú thích ở trên cùng của 'main': *** Giả sử *** rằng chữ ký' std :: function :: operator() 'đã thực sự là' R (Args && ...) '- điều này sẽ, với, nói, 'function ' tạo 'void (int &&)' cho toán tử '()', mà bây giờ sẽ chỉ chấp nhận các giá trị. – Xeo

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