C++11列表初始化

列表初始化:
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

时间: 2024-11-08 02:50:28

C++11列表初始化的相关文章

c++11——列表初始化

1. 使用列表初始化 在c++98/03中,对象的初始化方法有很多种,例如 int ar[3] = {1,2,3}; int arr[] = {1,2,3}; //普通数组 struct A{ int x; struct B{ int y; int z; } b; }a = {1, {3,4}}; //POD类型,可以直接使用memcpy复制的对象 int i = 0; Foo foo = f;//拷贝初始化 int i(0); Foo f(123); //直接初始化 在c++98/03中,普通

c++11之初始化列表

一.前言 C++的学习中,我想每个人都被变量定义和申明折磨过,比如我在大学笔试过的几家公司,都考察了const和变量,类型的不同排列组合,让你区别有啥不同.反正在学习C++过程中已经被折磨惯了,今天再来看看重温下那段"辉煌的历史".先来看一段代码: Player pa; // (a) Player pb(); // (b) Player pc = Player(); // (c) Player pd(Player()); // (d) pd = Player() // (e) a,b,

[C++11笔记001]修改通用库中的XDynamicArray,使它可以支持C++11的初始化列表和for循环

今天,有空翻了一下<C++Primer plus(第六版)>,看到里面有介绍新的for循环和初始化列表,但是我实现的动态数组XDynamicArray不支持这些新特性,没办法,只好进行改造了. 首先是for循环,如下面的样式 for(auto e:stList) { cout<<e<<endl; } 是于就各种google,和查找C++11的array的源代码,总结:就是提供一个标准的iterator和begin,end这两个方法,就可以了. 是于定义了一个iterat

C++11之列表初始化

1. 在C++98中,标准允许使用花括号{}来对数组元素进行统一的集合(列表)初始化操作,如:int buf[] = {0};int arr[] = {1,2,3,4,5,6,7,8}; 可是对于自定义的类型,却是无法这样去初始化的,比如STL标准模板库中容器,使用的频率非常之高,如vector,若要初始化其内容,则需要每次进行push_back 或使用迭代器去初始化,这是极其不便的.C++11 中,可以”列表初始化“方式来快速的初始化内置类型或STL中容器. 2.集合(列表)的初始化方式已经成

C++列表初始化

在C++11中,使用花括号来初始化变量得到全面的应用,也可以用花括号来对变量赋值.当用于内置类型变量时,这种初始化的一个重要特点是如果使用列表初始化且初始值存在丢失信息的风险,编译器将报错. int _tmain(int argc, _TCHAR* argv[]) { long double ld = 3.1415926536; int a{ ld }; int b = { ld }; int c(ld); int d = ld; return 0; } 编译将得到以下错误: (11): err

【共读Primer】51.[6.3]返回类型和return语句--列表初始化返回值 Page203

列表初始化返回值 C++11规定可以以列表初始化的方式来进行返回值的表达. vector<string> process() { if(expected.empty()) return {}; else if(expected == actual) return {"funcationX", "okay"}; else return {"funcationX", expected, actual}; } 主函数main的返回值 非vo

列表初始化 分析initializer_list&lt;T&gt;的实现

列表初始化(1)_统一初始化 1. 统一初始化(Uniform Initialization) (1)在C++11之前,很多程序员特别是初学者对如何初始化一个变量或对象的问题很容易出现困惑.因为可以用小括号.大括号或赋值操作符等多种方式进行初始化. (2)基于这个原因,C++11引入了“统一初始化”的概念.这意味着我们可以使用{}这种通用的语法在任何需要初始化的地方. [实例分析]初始化列表 #include <iostream> #include <vector> #includ

列表初始化

1 int var = 0; 2 int var = {0}; 3 int var {0}; 4 int var(0); 无论是初始化对象还是某些时候为对象赋新值,都可以用这样一组右花括号括起来的初始值. 当用于内置类型的变量时,这种初始化形式有一个重要特点:如果我们使用列表初始化且初始值存在丢失信息的风险,则编译器将报错,也就是说安全性比那些作转换的更高: 1 long double ld = 3.14 2 int a{ld},b={ld};// 错误:没发生转换,因为存在丢失信息的风险 3

Loadrunner 11.00 初始化失败; 通信错误。 Error (-81024): LR_VUG: The &#39;WS_SOAP&#39; type is not supported on &#39;WIN32&#39; platforms .

搜索LR安装目录bin文件夹下有个"wlrun.exe"的文件,邮件点击"属性"->"兼容性"->兼容模式中选择"windows 7",确认后重新打开即可,win10下是这个选项,其他操作系统挨个试一下,总有一个可以的! Loadrunner 11.00 初始化失败; 通信错误. Error (-81024): LR_VUG: The 'WS_SOAP' type is not supported on 'WIN3