2012-11-29 17 views
9

này hoạt động ...Sử dụng decltype và std :: chức năng với lambda

auto x = 4; 
typedef decltype(x) x_t; 
x_t y = 5; 

... vậy tại sao không này?

int j = 4; 
auto func = [&] (int i) { cout << "Hello: i=" << i << " j=" << j << endl;}; 
typedef decltype(func) lambda_t; 
lambda_t func2 = [&] (int i) { cout << "Bye: i=" << i << " j=" << j << endl;}; 

... và cách tôi khai báo lambda_t theo cách thủ công sử dụng std :: function?

Trả lời

14

... vậy tại sao điều này không hoạt động?

Bởi vì mỗi phiên bản từ vựng của lambda đều có một loại khác nhau. Nó không quan trọng nếu cùng một nhân vật được sử dụng.

.. và làm cách nào để tôi khai báo lambda_t theo cách thủ công sử dụng std :: function?

Lambda có một đối số int và không trả lại bất cứ điều gì ... Vì vậy:

loại
typedef std::function<void(int)> lambda_t; 
7

Lambda là không thể tả được (có thể không được đặt tên), đó là lý do bạn không thể làm những gì bạn đang hỏi. Bên cạnh đó, mỗi lambda là một loại khác nhau, vì vậy ngay cả khi bạn có thể đặt tên cho loại, bạn sẽ không thể gán lambda thứ hai đến đầu tiên. Nếu bạn nghĩ về cú pháp lambda như một phím tắt cho một đối tượng hàm trở nên rõ ràng hơn: thành viên operator() là khác nhau đối với mỗi lambda và do đó chúng thuộc các kiểu khác nhau.

Mặt khác, bạn có thể gán một lambda cho đối tượng std::function<> của chữ ký thích hợp, trong trường hợp của bạn là std::function<void(int)>.

+0

Bạn chắc chắn có thể nhập lambdas với decltype như thế. –

+1

@ R.MartinhoFernandes đặt câu hỏi tại sao 'decltype (func)' không trả về 'std :: function ' thay vì một số rác không sử dụng được? – learnvst

+1

@learnvst: Tại sao phải không? 'decltype' trả về kiểu khai báo, và một lambda là * không * một' std :: function'. Ngoài ra, 'std :: function' có hàm ý hiệu suất trong số những thứ khác, nhờ vào kiểu xóa. – Xeo

0

Đây là một số bằng chứng vững chắc cho thấy điều này không hiệu quả. Kịch bản tương tự:

int foo = 3; 
int bar = 3; 

std::cout << (typeid(foo).hash_code() == typeid(bar).hash_code()); // prints one -- obviously - they are the same type 

Bây giờ, hãy sử dụng cùng mã chính xác, nhưng với lambdas. Bạn nghĩ phản ứng sẽ như thế nào.

auto foo = [](){std::cout << "HELLO\n"; }; 

    auto bar = [](){std::cout << "HELLO\n"; }; 

    std::cout << (typeid(foo).hash_code() == typeid(bar).hash_code()); // prints 0 -- different type even though they are declared exactly the same.