bosthhe1 / cpushpush

0 stars 0 forks source link

可变参数模板 #45

Open bosthhe1 opened 1 year ago

bosthhe1 commented 1 year ago

可变参数模板顾名思义是模板参数是可变的,并不是固定的 我们先看书写形式

template<class...Args>//这里的Args为模板的参数包
void func1(Args...args)//这里的args是形参的参数包//模板参数包+形参参数包,形成一个参数包,这个参数包包含0到多个参数
{
    //
}

我们可以通过递归的方式来获得参数的类型,需要注意的是,这个参数必须写终止条件,这里是构成函数重载

template <class T>
void func1(const T& a)//当参数包中参数为1的时候,调用这个函数终止递归。
{
    cout << typeid(a).name() << endl;

}
template<class T, class...Args>
void func1(const T& a, Args...args)//每次取到参数包中第一个参数的类型,其余的当作一个参数包传下去,注意这里的const T&
{
    cout << typeid(a).name() << endl;
    func1(args...);//参数包必须以(args...)传递
}

测试: image

bosthhe1 commented 1 year ago

还有一种就是逗号表达式展开参数包

template<class T>
void Print(const T& a)//原理都差不多,用一个T类型的形成,来接受参数包中第一个参数,然后参数包将剩下的当中一个参数包
{
    cout << typeid(a).name() << endl;
}
template<class...Args>
void func1(Args...args)
{
    int a[] = { (Print(args), 0)... };
//这里是都好表达式,编译器会先处理参数包,然后将该位置设置为0,后面依次展开,参数包有多少个参数,数组就会被初时化多少个0
//注意这里的书写格式,和递归展开的格式不同,这个数组完全是只是为了参数包展开,没有别的意义
}

测试: image

bosthhe1 commented 1 year ago

在很多容器中看到 emplace_back(Args&&...args),就是使用的可变参数包,加万能引用,这个和push_bakc()对比,相差不大,push_back()也实现了右值引用,emplace_back(),是直接构造,而push_back(),是构造+资源转移,两者性能相差不大