可变参数

相同类型

  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只能是相同类型)
posted @ 2020-05-14 15:23  sfdevs  阅读(122)  评论(0)    收藏  举报