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

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

template< class T >
class initializer_list;

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

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

int a[] = {, , , };
std::vector<int> vec(a, a+sizeof(a));

或者

std::vector<int> vec;
vec.push_back();
vec.push_back();
vec.push_back();
vec.push_back();

有了initializer_list后,就可以直接像初始化数组一样:

class Test {

private:
static std::map<string, string> const nameToBirthday = {
{"lisi", ""},
{"zhangsan", ""},
{"wangwu", ""},
{"zhaoliu", ""},
};
}

当然啦,里面的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当出现在以下两种情况的被自动构造:

  1. 当初始化的时候使用的是大括号初始化,被自动构造。包括函数调用时和赋值
  2. 当涉及到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[], v.size()};
} }; template <typename T>
void templated_fn(T arg) {
for (auto a : arg)
cout << a << " ";
cout << endl;
} int main() {
S<int> s = {, , , , }; //automatically construct a initializer_list
// object and copy it
s.append({, , }); //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 : {-, -, }) //// the rule for auto makes this ranged for work
cout << x << " ";
cout << endl; auto al = {, , }; //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> > ({, , }); //ok
templated_fn<vector<int> >({, , }); //also ok return ;
}

Reference:

http://en.cppreference.com/w/cpp/utility/initializer_list

http://www.cppblog.com/liyiwen/archive/2009/07/26/91248.html

上一篇:android布局详解


下一篇:Spark Core知识点复习-1