Lambda函数的类型,使用自动 [英] Type of a lambda function, using auto

查看:77
本文介绍了Lambda函数的类型,使用自动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写c ++ lambda函数,并且不喜欢使用 auto 作为类型。当前看起来像这样:

  #include< iostream> 

int main(){
//将整数的地址发送到输出内容的函数;
auto print_int = [](int * a){std :: cout<< * a<< std :: endl;};
int a;
a = 3;
print_int(& a);
返回0;
}

但是,我想更改 auto std :: function< void(int)> 之类的东西,但不确定如何。





似乎相关,但我不确定如何适应它。谢谢。

解决方案

Lambda可以与 auto 或作为模板参数。您永远都不知道lambda的类型,也无法输入。每个Lambda都有自己独特的类型。即使您知道类型的名称,它们的类型名称通常也包含类型名称中禁止使用的字符。



为什么lambda有自己的类型?因为实际上,编译器会创建一个定义如下的类:

  struct / *未命名* / {

//函数体
auto operator()(int * a)const {
std :: cout<< * a<< std :: endl;
}

} print_int; //<-实例名称

此代码与等效代码非常接近(我省略了转换运算符) 。
如您所见,您已经使用了auto,因为lambda会推断出返回类型。



有人会说使用 std: :function< void(int *)> ,但我不同意。 std :: function 是可调用对象周围的多态包装。由于lambda是可调用的类型,因此它们适合其中。换句话说,它的工作方式与 std :: any 相似,但具有调用运算符。



那你应该怎么办?



使用 auto 自动还不错。实际上,它甚至可以使您的代码更快,并减少不必要的键入。如果您对 auto 感到不舒服,那不应该! auto 很棒,尤其是如果您没有选择;)



实际上,您可以避免使用通过使用模板参数 auto

  template< typename F,typename精氨酸
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 !但是,使用与 auto 相同的规则推导模板参数。实际上,使用简洁的功能模板,概念已被C ++ 20标准接受。您可以这样编写相同的函数模板:

  // C ++ 20 
void parametric_print(auto function, auto&&arg){
function(std :: forward< decltype(arg)>(arg));
}

如Oktalist所述,如果概念被接受为标准,则可以将 auto 替换为 Callable

  Callable print_int = [](int * a){std :: cout<< * a<< std :: endl; }; 

但是它不会导致不同的类型,它只是在推导类型时执行一些规则。 / p>

I am trying to write a c++ lambda function, and don't like having to use auto as the type. Currently it looks like:

#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;
}

However, I would like to change the auto to something like std::function<void(int)> but am not sure how. The answers to

seems relevant, but I am not sure how to adapt it. Thanks.

解决方案

Lambdas are meant to be used with either auto or as template parameter. You never know the type of a lambda and you can't type it. Each lambda has it's own unique type. Even if you knew the name of the type, their type names usually contains character prohibited in type names.

Why does lambda have their own type? because in reality, the compiler create a class defined a bit like that:

struct /* unnamed */ {

    // function body
    auto operator()(int* a) const {
        std::cout << *a << std::endl;
    }

} print_int; // <- instance name

This code is very close to an equivalent (I omitted conversion operator). As you can see, you already use auto, because lambdas are deducing the return type.

Some will say to use std::function<void(int*)>, but I disagree. std::function is a polymorphic wrapper around anything callable. Since lambdas are callable types, they fit into it. I other words, it work much like std::any but with a call operator. It will induce overhead in your application.

So what should you do?

use auto! auto isn't bad. In fact, it can even make your code faster and reduce unnecessary typing. If you feel uncomfortable with auto, well you shouldn't! auto is great, especially if you don't have the choice ;)

In fact, you could avoid using auto by using a template parameter:

template<typename F, typename Arg>
void parametric_print(F function, Arg&& arg) {
    function(std::forward<Arg>(arg));
}

Then use it like this:

int main() {
    int a = 3;
    parametric_print([](int* a) {std::cout << *a << std::endl;}, &a);
}

There you go, no auto! However, a template parameter is deduced with the same rule as auto. In fact, concept are accepted into the C++20 standard with terse function templates. You could write the same function template like this:

// C++20
void parametric_print(auto function, auto&& arg) {
    function(std::forward<decltype(arg)>(arg));
}

As mentionned by Oktalist, if concepts are accepted into the standard, then you could replace auto with Callable:

Callable print_int = [](int* a) { std::cout << *a << std::endl; };

But it does not result in a different type, it just enforce some rules when deducing the type.

这篇关于Lambda函数的类型,使用自动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆