前序内容:C++ 匿名函数详解(一)
三、匿名模板函数
- 从C++14(注意:C++11不支持)开始匿名函数支持模板编程,以下是例子:
#include
#include
#include
int main()
{
auto lambdafun= [=](auto a,auto b){
std::cout<<"a:"<<typeid(a).name()<<",b:"<<typeid(b).name()<<std::endl;
return a+b;
};
auto result1=lambdafun(1,2);
auto result2=lambdafun(1,2.0);
auto result3=lambdafun(1L,2.0F);
std::cout << typeid(result1).name()<<std::endl;
std::cout << typeid(result2).name()<<std::endl;
std::cout << typeid(result3).name()<<std::endl;
}
//p.s: c++的typeinfo虽然比较比较弱,但是基本类型还是可以的。
以下是输出:
a:i,b:i
a:i,b:d
a:l,b:f
i
d
f
可以看到,形参内的auto 等价于模板编程的class或者typename,唯一要注意的就是这里的三个auto是三个意思。
第1个和第2个auto, 形参的a,b 是独立的,这个类似class和typename;
但是函数的返回值,默认的auto,是根据模板编程推断出来的。
例子中分别对应int+int -> int, int+double->double, long+float->float。
- 从C++20开始,Lambda 支持auto与
风格(或者typename关键字)混用了 ,例如上面的函数等价于:
#include
#include
#include
int main()
{
auto lambdafun= [=](T a,auto b){
std::cout<<"a:"<<typeid(a).name()<<",b:"<<typeid(b).name()<<std::endl;
return a+b;
};
auto result1=lambdafun(1,2);
auto result2=lambdafun(1,2.0);
auto result3=lambdafun(1L,2.0F);
std::cout << typeid(result1).name()<<std::endl;
std::cout << typeid(result2).name()<<std::endl;
std::cout << typeid(result3).name()<<std::endl;
}
四、实际使用中匿名函数的注意点:
1、匿名函数会“匿名”
匿名函数不会被IDLE(例如Visual Studio)的辅助工具列举在函数列表内。因为匿名函数使用很方便,就算要反复使用,很多时候结合std::function 构成类的成员变量写起来比较简便。但是这么写,对于以后代码维护修改很不利,所以不该用匿名的时候别乱用。
2、引用捕获注意被引用的对象的生命周期
对于下面的例子:
#include
#include
#include
std::function fun;
void test()
{
int i=0;
fun=[&]()
{
i=i+1;
std::cout<<"i:"<<i<<std::endl;
};
fun();
}
int main()
{
test();
fun(); //执行异常
}
变量i被引用捕获后,其生命周期在test函数结束后结束,此时再执行fun调用i,就会执行异常。