怎么获取泛型的实际类型_C++20 新特性(12):使用模板语法的泛型lambda

在 C++14 中新增泛型lambda时,是使用基于 auto 的语法,比较简单但也带来一定的局限性,因此在 C++20 中进行改进,新增模板语法的泛型 lambda 。让我们先回顾一下基于 auto 语法的泛型 lambda ,以及其局限性,然后再看 C++20 新增的基于模板的泛型 lambda 。

d1627423592d6567c8b04fb3a4136a71.png

(C++14)基于 auto 的泛型 lambda

C++14 中的泛型 lambda ,是使用 lambda 参数中的 auto 关键字来表示不同的类型,一个例子如下:

#include #include using std::cout, std::endl, std::string;int main( int argc, char * argv[] ){    auto f1 = [] ( auto x, auto y ) { return x + y; };    cout << &f1 << endl;    string (*fp1)( string, string ) = f1;    double (*fp2)( double, int ) = f1;    cout << (void *)fp1 << " " << (void *)fp2 << endl;    double a1 = f1( 2, 5.0 );    string a2 = fp1( "2", "5.0" );    cout << a1 << " " << a2 << endl;    return 0;}

上述代码编译和执行的结果为:

[smlc@test code]$ g++ -std=c++20 a12.cpp[smlc@test code]$ ./a.out0x7ffcef96de2f0x401f18 0x401f4b7 25.0

由于 lambda 表达式实际定义的是一个闭包类(ClosureType),通过重载 operator () 来提供仿函数的调用。通过 auto 关键字定义的泛型 lambda ,相当于如下的定义:

struct {    template     auto operator() ( T x, U y ) const { return x + y; }};

基于 auto 的泛型 lambda 的局限性

基于 auto 的泛型 lambda ,最主要的局限性,是 auto 描述是整个类型,而不能像模板一样细化类型的模式。例如如果想 lambda 的参数类型是某种类型的数组(std::vector),当前基于 auto 的泛型 lambda 无法表示,只能将参数定义成所有类型,然后再通过其他手段限制只能是数组类型(std::vector),同时,如果想获取数组里面的具体类型,也需要使用其他手段来获取。

template  struct is_std_vector : std::false_type { };template  struct is_std_vector<:vector>> : std::true_type { };auto f = [ ] ( auto vecType ) {    static_assert( is_std_vector< decltype( vecType ) >::value, "" );  // <1> 额外的判断std::vector    using T = typename decltype( vecType )::value_type;  // <2> 使用其他手段获取数组的具体类型    // ... other code ...  };

其他还有很多类似的需要细化类型的情况,例如多个参数之间的类型有关联,或者是要去掉类型 const 等附加信息,这些都需要通过 decltype 来获取类型然后再进行各种处理,反而使代码更复杂了,因此增加模板语法的 lambda 是有必要的。

(C++20)新增基于模板的 lambda 语法

C++20中新增了基于模板的lambda语法,对于上面的情况可以更简洁的描述,和其他模板的语法也保持一致:

auto f = [ ] < typename T > ( std::vector vecType ) {  // <1> 无需额外判断std::vector,具体数组类型也可以直接使用T    // ... other code ...  }

语法上比较简单,不需要额外的 template 关键字,直接在 “ [ ] ” 和 “ ( ... ) ” 之间增加 “ < ... > ” 表示模板参数,然后在 lambda 参数和函数体中,就可以使用模板参数中描述的类型了。

基于模板的lambda也可以同时使用auto类型的参数,但不建议这样使用,混合使用这两种方式并不能带来额外的好处,反而使代码更加难懂。既然已经使用了模板,那么auto类型的参数也改为模板参数类型好了。

【往期回顾】

C++20 新特性(11):lambda对this的捕捉改进

C++20 新特性(10):字符串类型的改进

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值