C++11中std::initializer_list的使用
来源:互联网 发布:掌上电力数据如何更新 编辑:程序博客网 时间:2024/06/08 04:47
initializer_list是一种标准库类型,用于表示某种特定类型的值的数组。和vector一样,initializer_list也是一种模板类型,定义initializer_list对象时,必须说明列表中所含元素的类型。和vector不一样的是,initializer_list对象中的元素永远是常量值,我们无法改变initializer_list对象中元素的值。
initializer_list可以作用于可变数量的实参:有时我们无法提前预知应该向函数传递几个实参。为了编写能处理不同数量实参的函数,C++11新标准提供了两种主要的方法:如果所有的实参类型相同,可以传递一个名为initializer_list的标准库类型;如果实参的类型不同,我们可以编写一种特殊的函数,也就是所谓的可变参数模板。
作用于initializer_list对象的begin和end操作类似于vector对应的成员。begin()成员提供一个指向列表首元素的指针,end()成员提供一个指向列表尾元素的指针。
含有initializer_list形参的函数也可以同时拥有其他形参。
类模板initializer_list用于访问初始化列表(initialization list),列表元素的数据类型为const T.编译器从花括号(brace)封闭的、元素由逗号分隔开的初始化列表自动构造initializer_list模板类, 例如:
auto il = {10,20, 30}; // the type of il is an initializer_list<int>类模板initializer_list引用(refer to)但不包含这个这个列表的元素。复制这个initializer_list对象将引用到同一个基础列表而不是引用到基础列表的新的拷贝。std::initializer_list并不是一个容器,不要用它传递期望长期存储的值。构造函数的形参如果为一个initializer_list模板类,则这种特殊的构造函数称为初始化器列表构造函数(initializer_list constructor),例如:
struct myclass { myclass (int,int); myclass (initializer_list<int>); /* definitions ... */};myclass foo {10,20}; // calls initializer_list constructormyclass bar (10,20); // calls first constructor
仅可以从braced-init-list推导出initializer_list<T>。这一过程中,编译器自动查询哪些构造函数可以用initializer_list<T>作为参数,并据此确定initializer_list的模板参数T的类型,从而对braced-init-list做类型转换。
C++11标准明确规定不能由模板参数推导出对应实参std::initializer_list的类型。
C++还有一种特殊的形参类型(即省略符),可以用它传递可变数量的实参。
省略符形参是为了便于C++程序访问某些特殊的C代码而设置的,这些代码使用了名为varargs的C标准库功能。通常,省略符形参不应用于其他目的。省略符形参只能出现在形参列表的最后一个位置。
std::initializer_list:This type is used to access the values in a C++ initialization list, which is a list of elements of type const T.
下面是从其它文章中copy的std::initializer_list测试代码,详细内容介绍可以参考对应的reference:
#include "initializer_list.hpp"#include <initializer_list>#include <iostream>#include <string>#include <sstream>#include <vector>///////////////////////////////////////////////////////////////// reference: http://www.cplusplus.com/reference/initializer_list/initializer_list/struct myclass {std::string str;myclass(std::initializer_list<int> args) {std::stringstream ss;std::initializer_list<int>::iterator it; // same as: const int* itfor (it = args.begin(); it != args.end(); ++it) ss << ' ' << *it;str = ss.str();}};template<class T>struct simple_container {T * data;unsigned n;simple_container(std::initializer_list<int> args) {data = new T[args.size()];n = 0;for (T x : args) { data[n++] = x; }}T* begin() { return data; }T* end() { return data + n; }};template<class T>void print_list(std::initializer_list<T> il){for (const T* it = std::begin(il); it != std::end(il); ++it) std::cout << ' ' << *it;std::cout << '\n';}int test_initializer_list_1(){{std::initializer_list<int> mylist;mylist = { 10, 20, 30 };std::cout << "mylist contains:";for (int x : mylist) std::cout << ' ' << x;std::cout << '\n';}{myclass myobject{ 10, 20, 30 };std::cout << "myobject contains:" << myobject.str << '\n';}{simple_container<int> myobject{ 10, 20, 30 };std::cout << "myobject contains:";for (int x : myobject) std::cout << ' ' << x;std::cout << '\n';}{print_list({ 10, 20, 30 });}{// 编译器从花括号(brace)封闭的、元素由逗号分隔开的初始化列表自动构造initializer_list模板类auto il = { 10, 20, 30 };for (auto i : il)std::cout << i << " ";std::cout << std::endl;}return 0;}////////////////////////////////////////////////////////////////////// reference: http://en.cppreference.com/w/cpp/utility/initializer_listtemplate <class T>struct S {std::vector<T> v;S(std::initializer_list<T> l) : v(l) {std::cout << "constructed with a " << l.size() << "-element list\n";}void append(std::initializer_list<T> l) {v.insert(v.end(), l.begin(), l.end());}std::pair<const T*, std::size_t> c_arr() const {return{ &v[0], v.size() }; // copy list-initialization in return statement// this is NOT a use of std::initializer_list}};template <typename T>void templated_fn(T) {}int test_initializer_list_2(){S<int> s = { 1, 2, 3, 4, 5 }; // copy list-initializations.append({ 6, 7, 8 }); // list-initialization in function callstd::cout << "The vector size is now " << s.c_arr().second << " ints:\n";for (auto n : s.v)std::cout << n << ' ';std::cout << '\n';std::cout << "Range-for over brace-init-list: \n";for (int x : {-1, -2, -3}) // the rule for auto makes this ranged-for workstd::cout << x << ' ';std::cout << '\n';auto al = { 10, 11, 12 }; // special rule for autostd::cout << "The list bound to auto has size() = " << al.size() << '\n';// templated_fn({1, 2, 3}); // compiler error! "{1, 2, 3}" is not an expression,// it has no type, and so T cannot be deducedtemplated_fn<std::initializer_list<int>>({ 1, 2, 3 }); // OKtemplated_fn<std::vector<int>>({ 1, 2, 3 }); // also OKreturn 0;}
GitHub: https://github.com/fengbingchun/Messy_Test
- C++11中std::initializer_list的使用
- C++11特性--统一的初始化,std::initializer_list
- C++11中initializer_list的用法
- C++/C++11中std::transform的使用
- C++/C++11中std::queue的使用
- C++/C++11中std::priority_queue的使用
- C++/C++11中std::deque的使用
- C++/C++11中std::stack的使用
- C++/C++11中std::numeric_limits的使用
- C++/C++11中std::exception的使用
- C++/C++11中std::runtime_error的使用
- C++11中std::unordered_map的使用
- C++11中std::move的使用
- C++11中std::function的使用
- C++11中std::forward的使用
- C++11中std::bind的使用
- C++11中std::addressof的使用
- C++11中std::array的使用
- JVM类加载
- 【POJ】3250
- 古文觀止卷九_桐葉封弟辨_柳宗元
- 欢迎来到HelloWorld的世界
- zookeeper window下伪集群
- C++11中std::initializer_list的使用
- HBITMAP
- HTML和css面试题
- Android多进程时Application中onCreate执行多次
- ssh框架org.springframework.dao.InvalidDataAccessApiUsageException错误
- 秋细雨的日课十二条
- 原型模式
- 基于tinyXml2库封装的解析xml的通用类
- 怎么一次性删除PPT中所有动画效果?