c++initializer_list详解

素颜马尾好姑娘i 2022-06-15 02:44 235阅读 0赞

initializer_list是C++11提供的新类型,定义在头文件中。
用于表示某种特定类型的值的数组,和vector一样,initializer_list也是一种模板类型。

  1. template< class T >
  2. class initializer_list;

要介绍initializer_list的使用,有必要先谈一谈列表初始化。

C++11扩大了初始化列表的适用范围,使其可用于所有内置类型和用户定义的类型。无论是初始化对象还是某些时候为对象赋新值,都可以使用这样一组由花括号括起来的初始值了。使用初始化列表时,可添加=,也可不添加。

  1. //定义一个变量并初始化
  2. int units_sold=0;
  3. int units_sold(0);
  4. int units_sold={
  5. 0}; //列表初始化
  6. int units_sold{
  7. 0}; //列表初始化

当初始化列表用于内置类型的变量时,这种初始化形式有一个重要特点:如果我们使用列表初始化值存在丢失信息的风险,则编译器将报错:

  1. long double ld=3.1415926536;
  2. int a={ld},b={ld}; //错误:转换未执行,因为存在丢失信息的风险
  3. int c(ld),d=ld; //正确:转换执行,且确实丢失了部分值

列表初始化就谈到这里,接下来介绍initializer_list的使用
它提供的操作如下:

  1. initializer_list<T> lst;
  2. //默认初始化;T类型元素的空列表
  3. initializer_list<T> lst{a,b,c...};
  4. //lst的元素数量和初始值一样多;lst的元素是对应初始值的副本
  5. lst2(lst)
  6. lst2=lst
  7. //拷贝或赋值一个initializer_list对象不会拷贝列表中的元素;拷贝后,原始列表和副本元素共享
  8. lst.size() //列表中的元素数量
  9. lst.begin() //返回指向lst中首元素的指针
  10. lst.end() //返回指向lst中尾元素下一位置的指针

需要注意的是,initializer_list对象中的元素永远是常量值,我们无法改变initializer_list对象中元素的值。并且,拷贝或赋值一个initializer_list对象不会拷贝列表中的元素,其实只是引用而已,原始列表和副本共享元素。

和使用vector一样,我们也可以使用迭代器访问initializer_list里的元素

  1. void error_msg(initializer_list<string> il)
  2. {
  3. for(auto beg=il.begin();beg!=il.end();++beg)
  4. cout<<*beg<<" ";
  5. cout<<endl;
  6. }

如果想向initializer_list形参中传递一个值的序列,则必须把序列放在一对花括号内:

  1. //expected和actual是string对象
  2. if(expected != actual)
  3. error_msg({
  4. "functionX",expectde,actual});
  5. else
  6. error_msg({
  7. "functionX","okay"});

说了这么多,那initializer_list到底有什么应用呢?

有了initializer_list之后,对于STL的container的初始化就方便多了,比如以前初始化一个vector需要这样:

  1. std::vector v;
  2. v.push_back(1);
  3. v.push_back(2);
  4. v.push_back(3);
  5. v.push_back(4);

而现在c++11添加了initializer_list后,我们可以这样初始化

  1. std::vector v = { 1, 2, 3, 4 };

并且,C++11允许构造函数和其他函数把初始化列表当做参数。

  1. #include <iostream>
  2. #include <vector>
  3. class MyNumber
  4. {
  5. public:
  6. MyNumber(const std::initializer_list<int> &v) {
  7. for (auto itm : v) {
  8. mVec.push_back(itm);
  9. }
  10. }
  11. void print() {
  12. for (auto itm : mVec) {
  13. std::cout << itm << " ";
  14. }
  15. }
  16. private:
  17. std::vector<int> mVec;
  18. };
  19. int main()
  20. {
  21. MyNumber m = { 1, 2, 3, 4 };
  22. m.print(); // 1 2 3 4
  23. return 0;
  24. }

发表评论

表情:
评论列表 (有 0 条评论,235人围观)

还没有评论,来说两句吧...

相关阅读

    相关 NIO详解(五):Buffer详解

    1. 概述 Java NIO中的Buffer用于和NIO通道进行交互。如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的。缓冲区本质上是一块可以写入数据,然后可以从