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

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 套胶的胶皮与海绵分离怎么办 换肾15天了沒尿怎么办? 妻子的绒癌怎么办?——急人! 孕妇结石掉在输尿管有血尿怎么办 吃葯时药片沾在食管臂上怎么办 八十多了膀胱癌手术复发了怎么办 尿蛋白和尿隐血2个加怎么办 小肝癌手术后两个月又复发了怎么办 膀胱癌血尿堵塞尿道和尿管怎么办 肾炎腰疼一条腿疼尿血怎么办 孕晚期尿常规检查尿蛋白高怎么办? 腰开车疼的不会动了怎么办 小孩跑完满头大汗就咳嗽怎么办 小孩剧烈咳嗽喘吃了药不管用怎么办 做什么事都有点轻微的手抖怎么办 见到喜欢的人做事情就手抖怎么办 做了尿结石手术还尿血怎么办 宝宝十一个大运动发展缓慢怎么办 一岁八个月宝宝肚里有蛔虫怎么办 孕妇5个月了缺碘怎么办 4个月婴儿折了下腰怎么办 签了居间合同网签合同有异议怎么办 魅族3s手机返回键失灵怎么办 英语冠词和名词的关系用不好怎么办 炸好了的肉梭子不脆了怎么办 跑步的时候胸抖的疼怎么办 小区内安装了乒乓球桌扰民了怎么办 裁判出示红牌如果球员不走怎么办 高三文化课不好又没有特长怎么办 孩子做事磨蹭拖拉不讲效率怎么办 宝贝幼儿园哭的嗓子哑了怎么办 我给孩子转学学校不接收怎么办 眼睛被太阳晒了胀豉豉的怎么办 电脑电源灯亮着屏幕是黑的怎么办 刚办健身卡健身房跑路了怎么办 孕妇怀孕初期胖的太快怎么办 魔幻陀螺二的陀螺拆不动怎么办 我不干了小厂不给我发工资怎么办 货车司机把人撞成重伤没钱出怎么办 房主卖房定金收了不想卖怎么办 领导迟迟不给升职加薪机会怎么办