C++11提供的新类型,定义在
template< class T >
class initializer_list;
先说它的用处吧,然后再详细介绍一下。
首先有了initializer_list之后,对于STL的容器的初始化就方便多了,比如以前初始化一个vector需要这样:
int a[] = {0, 1, 2, 3};
std::vector
或者
std::vector
vec.push_back(1);
vec.push_back(3);
vec.push_back(3);
vec.push_back(2);
有了initializer_list后,就可以直接像初始化数组一样:std::vector
假设我有一个类,其中有需要一个“查询器”,根据不同人的名字得到生日(字符串),我们可以这么写:
class Test {
private:
static std::map
{"lisi", "18841011"},
{"zhangsan", "18850123"},
{"wangwu", "18870908"},
{"zhaoliu", "18810316"},
};
}
当然啦,里面的std::map必须提供参数为initializer_list的构造函数如:
map( std::initializer_list
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
#include
#include
using namespace std;
template
struct S {
vector
S(initializer_list
cout << "constructed with a " << l.size() << "-elements lists" << endl;
}
void append(std::initializer_list
v.insert(v.end(), l.begin(), l.end());
}
pair
return {&v[0], v.size()};
}
};
template
void templated_fn(T arg) {
for (auto a : arg)
cout << a << " ";
cout << endl;
}
int main() {
S
// 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
templated_fn
return 0;
}