C++11 ,添加了许多有用的功能,上章我们主要讲解了右值引用,这章我们来讲解可变参数模版的使用。
提示:以下是本篇文章正文内容,下面案例可供参考
示例代码如下:
以往我们见过这样的可变参数列表
而C++11则引入了可变参数模版
template<class ...Args>
void Func(Args... args)
{
cout << sizeof...(args) << endl; //可以通过sizeof这样的语法格式来查看args包有几个参数
}
int main()
{
string str = "hello world";
Func(1);
Func(1, 'a', 2);
Func(1, 'a', str);
return 0;
}
这里的Args是类型名,args是类型对象,也是可变参数包,里面可以包含着0~n个参数。
对于可变参数模版的解析,从现在步入C++11开始,我们就可以明显感觉到C++与之前似乎有些不同了,它的新添加的功能使用与我们之前转换了一种新的风格。
如果要解析可变参数包,可以使用递归函数的方式来解析。
代码如下(示例):
void _Func()
{
cout << endl;
}
template<class T, class ...Args>
void _Func(const T& data, Args ...args)
{
cout << data << " ";
_Func(args...);
}
template<class ...Args>
void Func(Args... args)
{
cout << sizeof...(args) << " "; //可以通过sizeof这样的语法格式来查看args包有几个参数
_Func(args...);
}
int main()
{
string str = "hello world";
Func(1);
Func(1, 'a', 2);
Func(1, 'a', str);
return 0;
}
可变参数模版,最多使用于库里面,日常生活中我们很少会去使用可变参数模版,除非你要去实现一个库函数,例如在C++11之后,容器基本都添加了一个emplace_back的函数
它的用法与push_back相同,但是在应用方面比push_back更有优势!
下面我们就来看一段代码
代码如下(示例):
如果使用push_back,由于我们的vector的模版T是pair,我们在第一个push_back加上一个{}进行pair的隐式类型转换才能成功插入.
而第二个push_back,因为其vector没有该构造函数所以直接编译错误。
第二个emplace_back,因为是可变参数列表,没办法识别{2,“李四”}这个类型,所以编译报错。
那emplace_back,做了什么处理? 它没有进行任何的隐式类型转换,也就说明减少了一次构造,**(再结合我们上章内容讲的右值引用,发生隐式类型转换就说明这是一个匿名对象,对于匿名对象我们通常就会去走右值引用的移动构造)**所以emplace_back采用的可变参数模版的方式,就可以减少隐式类型转换的构造,直接在底层函数进行直接构造,在这种情况下,如果类型足够复杂可以提高程序效率,并且在底层不断使用forward(x)不断保持其原有的左右值属性,最后再去new 可变参数包里的所有类型,然后根据左右值该进行拷贝构造的进行拷贝构造,该进行移动构造的进行移动构造。(十分复杂)
对于可变参数模版的理解,我们还是要自己手动去练习,这样才能更好的理解与运用它,不过也不必过于深究,仅需了解即可。