我正在尝试编写一个c lambda函数,并且不喜欢使用auto作为类型.目前它看起来像:
#include <iostream> int main() { // Sends the address of an integer to a function which prints out the contents; auto print_int = [](int* a) {std::cout << *a << std::endl;}; int a; a = 3; print_int(&a); return 0; }
但是,我想将auto改为类似std :: function< void(int)>但我不确定如何.答案
> What is the type of a lambda function?
似乎相关,但我不知道如何适应它.谢谢.
解决方法
Lambdas旨在与auto或as模板参数一起使用.你永远不知道lambda的类型,你不能输入它.每个lambda都有自己独特的类型.即使您知道该类型的名称,它们的类型名称通常也包含类型名称中禁止的字符.
为什么lambda有自己的类型?因为实际上,编译器创建了一个类似于这样的类:
struct /* unnamed */ { // function body auto operator()(int* a) const { std::cout << *a << std::endl; } } print_int; // <- instance name
这段代码非常接近等价(我省略了转换运算符).
如您所见,您已经使用auto,因为lambdas正在推断返回类型.
有人会说使用std :: function< void(int *)>,但我不同意. std :: function是一个围绕任何可调用的多态包装器.由于lambdas是可调用类型,因此它们适合它.换句话说,它的工作方式与std :: any非常相似,但有一个调用操作符.它会在您的应用程序中产生开销.
那你该怎么办?
用汽车!汽车还不错.实际上,它甚至可以使您的代码更快,并减少不必要的输入.如果你对汽车感到不舒服,那么你不应该!汽车是伟大的,特别是如果你没有选择;)
实际上,您可以通过使用模板参数来避免使用auto:
template<typename F,typename Arg> void parametric_print(F function,Arg&& arg) { function(std::forward<Arg>(arg)); }
然后像这样使用它:
int main() { int a = 3; parametric_print([](int* a) {std::cout << *a << std::endl;},&a); }
你去,没有汽车!但是,使用与auto相同的规则推导出模板参数.事实上,如果概念被接受到标准中,您可以编写相同的函数模板,如下所示:
// maybe C++20 void parametric_print(auto function,auto&& arg) { function(std::forward<decltype(arg)>(arg)); }
正如Oktalist所提到的,如果标准中接受了概念,那么你可以用Callable替换auto:
Callable print_int = [](int* a) { std::cout << *a << std::endl; };
但它不会产生不同的类型,它只是在推断类型时强制执行一些规则.