c++的initializer_list

引入的目的或者主要用处

  • 如果我们的函数无法事先知道函数要传入的参数是多少,是什么类型,即要定义未知数量,未知类型的形参,要怎么定义呢,
    一般是用省略号形参来定义,如: printf(char *format...)
    c++11为我们再提供两种主要的方法:
    • 可变参数模板,它和省略号差不多,但还有更加强大的用处
    • 如果传入的参数类型相同,但是数量不定的话,那就是我们的initializer_list了
  • 变量或者对象的定义常用的大括号,中挂号,赋值符号

    Rect r1 = {3, 7, 20, 50};
    Rect r2{3, 7, 20, 50};
    int a[6] = {0, 1, 2, 0, 1, 2};

    c++11提出了Unifrom Initialization(一致性初始化)的概念,也就是初始化可以都用一样的形式,大括号的内容就是initializer_list

    double b{9.9}
    int values[] v{0, 1, 2, 0, 1, 2};
    vector cities{"beijing", "shanghai"};

initializer_list的定义和使用

这个是一个标准库模板类,它内部使用的是array,比较简单

需要注意的是
1.拷贝或者复制是浅拷贝,两个对象共享元素
2.对象中的元素永远是const,我们无法改变内部的值

  • 对于参数数量不定的举个代码:
#include <iostream>
#include <initializer_list>
using namespace std;

void error_msg(int ErrCode, initializer_list<string> il)
{
    cout << "errno(" << ErrCode << "): ";
    for (auto beg = il.begin(); beg != il.end(); ++beg)
        cout << *beg << " " ;
    cout << endl;
}

int main()
{
    error_msg(2, {"ENOENT", "No such file or directory!"});
}

运行结果:

  • 一致性初始化
    初始化是编译器做的工作,比如定义变量complex<double> c{5.6, 6.7},编译器会生成initializer_list< double >,调用构造函数时编译器会分解元素并
    逐一传递给函数,当然如果构造函数就有用initializer_list做参数的,那就直接传进去就可以,不需要分解
    现在的stl标准库都有这种构造,比如vector:
    vector(initializer_list<value_type> __l, const allocator_type& __a = allocator_type())
    那么可以像数组那样定义而不用一个个append:
    vector<int> a{1, 2, 3, 4, 5, 6, 7};

参考

猜你喜欢

转载自www.cnblogs.com/ljqblogs/p/12185230.html