C++11中新特性之:initializer_list详解

  • Post author:
  • Post category:其他


C++11提供的新类型,定义在<initializer_list>头文件中。

template< class T >

class initializer_list;

先说它的用处吧,然后再详细介绍一下。

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

int a[] = {0, 1, 2, 3};

std::vector<int> vec(a, a+sizeof(a));

或者

std::vector<int> vec;

vec.push_back(1);

vec.push_back(3);

vec.push_back(3);

vec.push_back(2);

有了initializer_list后,就可以直接像初始化数组一样:std::vector<int> vec = {0, 2, 3, 5};

假设我有一个类,其中有需要一个“查询器”,根据不同人的名字得到生日(字符串),我们可以这么写:

class Test {

private:

static std::map<string, string> const nameToBirthday = {


{“lisi”, “18841011”},

{“zhangsan”, “18850123”},

{“wangwu”, “18870908”},

{“zhaoliu”, “18810316”},

};

}

当然啦,里面的std::map必须提供参数为initializer_list的构造函数如:

map( std::initializer_list<value_type> init,

const Compare& comp = Compare(),

const Allocator& alloc = Allocator() );

其实for(initializer: list)中如果list是个形如:{a, b, c…},那么其实list自动被构造成了initializer_list对象。

下面稍微介绍一下initializer_list

一个initializer_list当出现在以下两种情况的被自动构造:

当初始化的时候使用的是大括号初始化,被自动构造。包括函数调用时和赋值

当涉及到for(initializer: list),list被自动构造成initializer_list对象

也就是说initializer_list对象只能用大括号{}初始化。

拷贝一个initializer_list对象并不会拷贝里面的元素。其实只是引用而已。而且里面的元素全部都是const的。

下面一个例子可以帮助我们更好的理解如何使用initializer_list:

#include <iostream>

#include <vector>

#include <initializer_list>

using namespace std;

template <class T>

struct S {


vector<T> v;

S(initializer_list<T> l) : v(l){


cout << “constructed with a ” << l.size() << “-elements lists” << endl;

}

void append(std::initializer_list<T> l) {


v.insert(v.end(), l.begin(), l.end());

}

pair<const T*, size_t> c_arr() const{


return {&v[0], v.size()};

}

};


template  <typename T>

void templated_fn(T arg) {


for (auto a : arg)

cout << a << ” “;

cout << endl;

}

int main() {


S<int> s = {1, 2, 3, 4, 5}; //automatically construct a initializer_list

// object and copy it

s.append({6, 7 , 8});         //list-initialization in function call

cout << “The vector size is now ” << s.c_arr().second << ” ints:” << endl;

for (auto n : s.v)

cout << ‘ ‘ << n;

cout << endl;

cout << “range-for over brace-init-list: ” << endl;

for (auto x : {-1, -2, 03})   the rule for auto makes this ranged for work

cout << x << ” “;

cout << endl;

auto al = {10, 11, 12};  //special rule for auto

cout << “The list bound to auto has size() = ” << al.size() << endl;


//templated_fn({1, 2, 3});   //compiler error! “{1, 2, 3}” is not an expressionit has no type, and so T cannot be duduced.

templated_fn<initializer_list<int> > ({7, 8, 9}); //ok

templated_fn<vector<int> >({3, 5, 7});           //also ok

return 0;

}



版权声明:本文为weixin_51725434原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。