Bạn không bao giờ có thể biết loại chức năng lambda bởi vì những gì hợp lý xảy ra là trình biên dịch tạo ra một lớp (địa phương) với chức năng điều hành cuộc gọi quá tải và một đóng cửa từ vựng được đại diện bởi các thành viên dữ liệu của lớp đó (địa phương). Đây là những gì hợp lý xảy ra đối với một hàm lambda như:
auto foo = [](int x, int y) { return x + y; };
Trình biên dịch một cách logic thực hiện điều này:
struct CompilerGeneratedName { void operator()(int x, int y) const { return x + y; } };
CompilerGeneratedName foo;
Kể từ khi trình biên dịch tạo ra một lớp (địa phương), nó tạo ra một tên và do đó bạn có thể không bao giờ viết một cách rõ ràng loại, bạn chỉ có thể suy ra loại từ các loại khấu trừ của các đối số hàm mẫu hoặc sử dụng auto/decltype.
Ngoài ra đóng C++ 0x được phân bổ tĩnh nên bạn không thể trả lại một cách an toàn nguyên bản đóng C++ 0x.
Vẫn có một vài cách bạn có thể đạt được điều này, đầu tiên là linh hoạt hơn và hỗ trợ các hàm lambda nắm bắt phạm vi từ vựng. Sử dụng std :: function, nếu bạn có hàm lambda không capture bất cứ thứ gì từ phạm vi bên ngoài thì bạn có thể sử dụng con trỏ hàm nhưng chuyển đổi này là nhiều hơn để làm việc với mã cũ hơn bất cứ thứ gì.
Vì vậy, về cơ bản những gì bạn muốn là thế này:
std::function< int (int) > foo(int x)
{
return [x](int y)->int{return x * y;};
}
Lý do tại sao tôi tiếp tục nói một cách logic, là bởi vì đây là cách thúc đẩy :: lambda loại công trình ban đầu (mặc dù C++ 03 không cho phép các lớp địa phương được sử dụng trong các đối số hàm mẫu) và nơi mà ý tưởng thêm hàm lambda bắt nguồn từ nhưng vì đây là một tính năng ngôn ngữ giờ đây các nhà cung cấp trình biên dịch có thể thực hiện nó theo các cách khác nhau và hiệu quả hơn như khi chụp tất cả môi trường. chỉ có thể chuyển một con trỏ tới ngăn xếp cuộc gọi thay vì theo cách hợp lý trong khi vẫn duy trì chế độ xem logic.
Nguồn
2010-07-01 20:21:42
Cảm ơn, +1. Những gì bạn có nghĩa là bởi "nếu bạn lambda chức năng không phải là chụp bất cứ điều gì từ phạm vi bên ngoài sau đó bạn có thể sử dụng con trỏ chức năng."? Nó không phải là x? – Cam
@incrediman có ví dụ của bạn là chụp vì vậy bạn không thể sử dụng con trỏ hàm, chỉ các hàm lambda không có trạng thái có thể được chuyển đổi thành con trỏ hàm. –
@snk_kid: Ồ. Tôi thực sự chỉ đọc sai những gì bạn đã viết, nó làm cho cảm giác hoàn hảo cách nó là :) – Cam