MSalters lưu ý rằng "lambda không bắt được có thể được chuyển đổi thành con trỏ thành hàm." Điều đó có nghĩa là gì? Đối tượng lambda sẽ khớp với một con trỏ trỏ đến kiểu tham số hàm.
Thật khó để dịch loại lambda thành con trỏ thành hàm. Đây là nỗ lực của tôi trong việc triển khai tuân thủ. Đó là hơi hackish.
#include <type_traits>
template< typename fn >
struct ptmf_to_pf;
template< typename r, typename c, typename ... a >
struct ptmf_to_pf< r (c::*) (a ...) const >
{ typedef r (* type)(a ...); };
// Use SFINAE to hide function if lambda is not convertible to function ptr.
// Only check that the conversion is legal, it never actually occurs.
template< typename lambda >
typename std::enable_if< std::is_constructible<
typename ptmf_to_pf< decltype(&lambda::operator()) >::type,
lambda >::value >::type
f(lambda arg) {
arg("hello ");
arg("world\n");
}
#include <iostream>
int main() {
int x = 3;
f([](char const *s){ std::cout << s; }); // OK
f([=](char const *s){ std::cout << s; }); // OK
f([=](char const *s){ std::cout << s << x; }); // error
}
Điều này sẽ không chấp nhận con trỏ hàm làm đối số trực tiếp, vì thông số mẫu cần phải giải quyết cho một hàm. Bạn có thể làm cho nó làm như vậy bằng cách cung cấp một chuyên môn cho ptmf_to_pf
chấp nhận con trỏ đến các loại chức năng.
Ngoài ra, như bản trình diễn cho thấy, nó sẽ không chấp nhận lambdas nắm bắt bất cứ điều gì theo giá trị, cũng như bằng cách tham chiếu. Không có cách nào trong C++ để hạn chế cụ thể như vậy.
Khi đối tượng đóng cửa chạm vào chức năng của bạn, nó đã được xây dựng, và bạn không có ý tưởng gì bên trong ruột của nó, vì chúng là riêng tư. Nhưng trong trường hợp bạn đang tự hỏi, lambda chắc chắn không thể nắm bắt bất cứ điều gì * sau thực tế *, và đặc biệt không có gì từ bên trong * hàm * 'f' của bạn. –
Điều này sẽ là vô nghĩa, vì việc chụp con trỏ theo giá trị cũng nguy hiểm như việc chụp tham chiếu. –
@BenVoigt Đúng vậy. – log0