注解:下面的代码测试环境为ubuntu22.04,编译器版本gcc version 11.2.0 ,部分版本较低的编译器不支持下面的部分语法。
1.auto自动类型推导
#include <iostream>
using namespace std;
auto add(auto a, auto b)
{
return a + b;
}
int main()
{
cout << add(1, 2) << endl;
cout << add(1.1, 2.0) << endl;
}
可以看到正常的输出结果,这种情况下,函数的传入参数类型,返回值类型都可以不进行指定,提高了代码复用性 ,甚至于可以直接用auto定义函数指针,而不用我们去写复杂的函数指针定义式子。利用auto的自动类型推导的特性,可以让编译器来操心变量的类型,大大提高我们的开发效率。
2.变长参数模板
我们常用的printf函数,就是一个很明显的可变参数函数,即参数的数量与类型不固定,C++中刚好有这种类似的模板语法,即变长参数模板,对于这种类型的函数,我们一般的操作是,先解析出变参的个数,再执行对应的动作
2.1递归调用解析参数方法
#include <iostream>
using namespace std;
template<typename T1>
auto print(T1 value)
{
cout<<value<<endl;
}
template<typename T1,typename...T2>
auto print(T1 value,T2...args)
{
cout<<value<<endl;
print(args...);
}
int main()
{
print("123",1,2,3);
}
这里解释一下上述代码:
首先主函数中定义了一个模板函数(看起来有两个,其实只有一个,上面一个函数是递归调用的出口而已),首先看调用函数的时候参数个数,很明显,参数数量大于1,直接进入第二个模板函数,这里先进行一次输出打印,然后第二个参数继续进行递归调用,第二个参数变成第一个,继续进行嵌套调用,当运行到最后一个参数时,到达函数调用出口,调用第一个函数进行输出,然后结束。
2.2条件判断解析参数个数
#include <iostream>
using namespace std;
template<typename ...T1>
auto print(T1...t)
{
cout<<"参数个数为:"<<sizeof...(t)<<endl;
}
int main()
{
print(1);
print(1,2);
print(1,2,3);
}
这里首先我们需要知道,我们能够通过sizeof来计算可变参数的个数。
这里需要使用一个关键字:constexpr
具体见:constexpr修饰模板函数
条件判断使用:
#include <iostream>
using namespace std;
template<typename T0,typename ...T1>
auto print(T0 t0,T1...t)
{
cout<<t0<<endl;
if constexpr (sizeof...(t)>0)
print(t...);
}
int main()
{
print(1);
print(1,2);
print(1,2,3);
}
3.初始化列表搭配lambda表达式
#include <iostream>
using namespace std;
template<typename T0,typename ...T1>
auto print(T0 t0,T1...t)
{
cout<<t0<<endl;
std::initializer_list<T0>{
([&t]{
cout<<t<<endl;
}(),t0)...
};
}
int main()
{
print(1);
print(1,2);
print(1,2,3);
}
本文含有隐藏内容,请 开通VIP 后查看