列表初始化:
1.旧语法中定义了初始化的几种不同形式,如下:
int data = 0; //赋值初始化
int data = {0}; //花括号初始化
int data(0); //构造初始化
int data{0}; //花括号初始化
2.C++11以旧语法中花括号初始化形式为基础,设计了列表初始化语法,统一了不同的初始化形式。
数据类型 变量{初始化列表}
1 #include <iostream> 2 #include <iterator> 3 using namespace std; 4 5 struct Student 6 { 7 char name[256]; 8 struct Date 9 { 10 int year; 11 int month; 12 int day; 13 }bday; 14 }; 15 16 class Complex 17 { 18 public: 19 Complex(double r = 0, double i = 0) :m_r(r), m_i(i){} 20 friend ostream& operator<<(ostream &os, Complex const &that) 21 { 22 return os << that.m_r << "+"<<that.m_i << "i" ; 23 } 24 Complex(Complex const &that) :m_r(that.m_r), m_i(that.m_i) 25 { 26 cout << "拷贝构造函数" << &that << "->" << this << endl; 27 } 28 private: 29 double m_r, m_i; 30 }; 31 int main() 32 { 33 int a{ 123 }; 34 cout << a << endl; 35 double b{ 3.4567 }; 36 cout << b << endl; 37 int c[]{100, 200, 300}; 38 copy(c, c + sizeof(c) / sizeof(c[0]), ostream_iterator<decltype(*c)>(cout, " ")); 39 cout << endl; 40 Student d{ "张飞", { 2000, 1, 1 } }; 41 cout << d.name << "," << d.bday.year << "-" << d.bday.month << "-" << d.bday.day << endl; 42 Complex e{ 1.2, 3.4 }; 43 cout << e << endl; 44 Complex *f = new Complex{ 1.2, 3.4 }; 45 cout << *f << endl; 46 delete f; 47 f = new Complex[3]{{ 1.1, 2.2 }, { 2.2, 3.3 }, { 3.3, 4.4 }}; 48 copy(f, f + 3, ostream_iterator<decltype(*f)>(cout, " ")); 49 cout << endl; 50 delete[] f; 51 cout << Complex{ 1.2, 3.4 } << endl; 52 //Complex const (&h)[3]{{ 1.1, 2.2 }, { 2.2, 3.3 }, { 3.3, 4.4 }}; 53 Complex const h[3]{{ 1.1, 2.2 }, { 2.2, 3.3 }, { 3.3, 4.4 }}; 54 copy(h, h + 3, ostream_iterator<decltype(*h)>(cout, " ")); 55 cout << endl; 56 Complex i = e; 57 //Complex i = Complex(1.2, 3.4); 58 cout << i << endl; 59 getchar(); 60 return 0; 61 }
3. 变长初始化表,initializer_list
1 #include <iostream> 2 #include <iterator> 3 #include <vector> 4 #include <map> 5 using namespace std; 6 7 class A 8 { 9 public: 10 A(initializer_list<int> li) 11 { 12 for (auto it = li.begin(); it != li.end();++it) 13 { 14 m_vi.push_back(*it); 15 } 16 } 17 friend ostream &operator<<(ostream &os, A const &that) 18 { 19 copy(that.m_vi.begin(), that.m_vi.end(), ostream_iterator<decltype(that.m_vi[0])>(os, " ")); 20 return os; 21 } 22 private: 23 vector<int> m_vi; 24 }; 25 26 int average(initializer_list<int> scores) 27 { 28 if (!scores.size()) 29 return 0; 30 int sum = 0; 31 for (auto it = scores.begin(); it != scores.end(); ++it) 32 sum += *it; 33 return sum / scores.size(); 34 } 35 36 int _tmain(int argc, _TCHAR* argv[]) 37 { 38 char const *a[]{ "张飞", "赵云", "关羽", "黄忠", "马超" }; 39 copy(a, a + sizeof(a) / sizeof(a[0]), ostream_iterator<decltype(a[0])>(cout, " ")); 40 cout << endl; 41 vector<const char *> b{ "张飞", "赵云", "关羽", "黄忠", "马超" }; 42 copy(b.begin(),b.end(),ostream_iterator<decltype(b[0])>(cout, " ")); 43 cout << endl; 44 map<const char *, int> c{ { "张飞", 100 }, { "赵云", 50 }, { "关羽", 25 } }; 45 for (auto it = c.begin(); it != c.end(); ++it) 46 cout << it->first << ":" << it->second << endl; 47 /*for (map<const char *, int>::iterator it = c.begin(); it != c.end(); ++it) 48 cout << it->first << ":" << it->second << endl;*/ 49 A a1{ 1, 3, 5, 7, 9 }; 50 cout << a1 << endl; 51 A a2{ 2,4,6,8,10 }; 52 cout << a2 << endl; 53 int d = 60, e = 70, f = 80; 54 cout << average({ d,e,f }) << endl; 55 cout << average({ 50,d, e, f,90 }) << endl; 56 getchar(); 57 return 0; 58 }
4.聚合类型
(4.1)任意类型的数组
(4.2)满足特定条件的类:
a 无自定义的构造函数
b 无私有或者保护的非静态成员变量
c 无基类
d 无虚函数
e 无通过“=”或者“{}”在类声明部分被初始化的非静态成员变量
(4.3)聚合类型的元素或者成员可以是聚合类型也可以是非聚合类型
(4.4)对聚合类型使用列表初始化,相当于对其中的元素逐一初始化,
而对非聚合类型使用列表初始化,相当于用列表初始化的值作为参数,调用相应的构造函数。
5.initializer_list作为轻量级的列表容器,不但可以用在构造函数中,
也可以作为普通函数的参数,传递不定数量的实参,相对于传统标准容器,
效率更高(轻量级列表容器,仅保存初始化列表元素的引用,而非其副本)
1 #include "stdafx.h" 2 #include <iostream> 3 #include <iterator> 4 #include <list> 5 using namespace std; 6 7 //轻量级列表容器内部存放初始化列表元素的引用而非其拷贝 8 initializer_list<int> light(void) 9 { 10 int a = 1000, b = 2000, c = 3000; 11 //返回局部变量的引用将在函数返回以后失效 12 return{ a,b,c }; 13 } 14 15 //重量级容器内部存放初始化列表元素的拷贝而非其引用 16 list<int> heavy(void) 17 { 18 int a = 1000, b = 2000, c = 3000; 19 //所返回局部变量拷贝在函数返回后继续有效 20 return{ a, b, c }; 21 } 22 23 int _tmain(int argc, _TCHAR* argv[]) 24 { 25 //可以接受任意长度的初始化列表,但列表中元素的类型必须相同 26 initializer_list<int> initlist{ 10, 20, 30, 40, 50, 60 }; 27 //initilizer_list只有三个公有成员:begin,end,size 28 copy(initlist.begin(), initlist.end(), ostream_iterator<decltype(*initlist.begin())>(cout, " ")); 29 cout << "[" << initlist.size() << "]" << endl; 30 31 //迭代器为只读类型,其目标元素不可修改 32 /*for (auto it = initlist.begin(); it != initlist.end();++it) 33 { 34 *it *= 100; 35 }*/ 36 37 //可以对容器整体赋值 38 initlist = { 100, 200, 300 }; 39 copy(initlist.begin(), initlist.end(), ostream_iterator<decltype(*initlist.begin())>(cout, " ")); 40 cout << "[" << initlist.size() << "]" << endl; 41 //提供缺省构造函数,用于实例化空容器 42 initlist = {}; 43 copy(initlist.begin(), initlist.end(), ostream_iterator<decltype(*initlist.begin())>(cout, " ")); 44 cout << "[" << initlist.size() << "]" << endl; 45 initlist = light(); 46 copy(initlist.begin(), initlist.end(), ostream_iterator<decltype(*initlist.begin())>(cout, " ")); 47 cout << "[" << initlist.size() << "]" << endl; 48 list<int> li = heavy(); 49 copy(li.begin(), li.end(), ostream_iterator<decltype(*li.begin())>(cout, " ")); 50 cout << "[" << li.size() << "]" << endl; 51 getchar(); 52 return 0; 53 }
6.列表初始化可以防止类型收窄,即对可能造成信息损失的类型转换,提示警告或者直接报错
long double ld = 3.1415926;
int a{ld},b{ld}; //error,转换未执行,因为存在丢失信息的危险
int a(ld),b(ld); //true,转换执行,且确实丢失了部分值
原文地址:https://www.cnblogs.com/LuckCoder/p/8467656.html