可变参数
相同类型
initializer_list对象中的元素永远是常量值,我们无法改变initializer_list对象中元素的值。并且,拷贝或赋值一个initializer_list对象不会拷贝列表中的元素,其实只是引用而已,原始列表和副本共享元素。(没有看源码,估计是通过智能指针保留原始对象的强或弱引用)
void test_copy()
{
std::initializer_list<std::string> lst_cp1;
{
std::initializer_list<std::string> lst{"this", "is", "a", "test", "!"};
for(auto &it : lst)
std::cout << it << " addr : " << (&it) << std::endl;
lst_cp1 = lst;
}
for(auto &it : lst_cp1)
std::cout << it << " addr : " << &it << std::endl;
}
## output :
this addr : 0x7ffc966987b0
is addr : 0x7ffc966987d0
a addr : 0x7ffc966987f0
test addr : 0x7ffc96698810
! addr : 0x7ffc96698830
this addr : 0x7ffc966987b0
is addr : 0x7ffc966987d0
a addr : 0x7ffc966987f0
test addr : 0x7ffc96698810
! addr : 0x7ffc96698830
std::string use(const std::initializer_list<std::string> &li)
{
...
}
use({"this", "is", "a", "string"});
不同类型
Args是一个模板参数包
rest是一个函数参数包
- 递归展开
template<typename T>
std::ostream& print(std::ostream& os, const T& t)
{
return os << t;
}
template<typename T, typename... Args>
std::ostream& print(std::ostream& os, const T& t, const Args&... args)
{
os << t << ", ";
return print(os, args...);
}
print(std::cout, 1, 2.3, 'c', "good", std::string("life"));
- 逗号表达式展开参数包
void pt(T t)
{
// std::cout << t << std::endl;
}
template <class... Args>
void expend(Args... args)
{
std::cout << sizeof...(Args) << std::endl;
int arr[] = {(pt(args),0)...};
}
template<class F, class... Args>void expand(const F& f, Args&&...args)
{
std::initializer_list<int>{(f(std::forward< Args>(args)),0)...};
}
expand([](int i){std::cout<< i << std::endl;}, 1, 2, 3, 4, 5); (initializer_list只能是相同类型)