c++11 统一初始化
Posted zkccpro
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++11 统一初始化相关的知识,希望对你有一定的参考价值。
c++11 统一初始化
一、c++98/03的初始化方式
-
括号初始化
int a(2);//ctor(尽管这个例子貌似不是很恰当) int b(a);//c-ctor
-
列表初始化:
//c++98/03的列表初始化用于初始化数组 int arr1[3] = 1, 2, 3 ; int arr2[] = 1, 3, 2, 4 ; //c++98/03的列表初始化用于初始化结构体变量(貌似不太常用) struct A int a; int b; int c; ; A a1,2,3;//但这样做明显有溢出危险啊。。(比如把A::c的类型换成char)
二、c++11的统一初始化
- 变量初始化:
class A
public:
A()=default;
A(int a):a_(a)
A(int a,int b):a_(a)
int a_;
;
int main()
A aa1(2);//c++98的写法,有时候小括号容易与函数冲突了,所以c++11之后最好不要这么用
A aa22;//这种写法是推荐的,效果和aa1一样
A aa3=2;//这种写法容易引起歧义,最好不要写,但和aa2的效果是一样的
A aa42,3;
-
new对象初始化:
int* a=new int2;//和小括号一样 int* a=new int[2]1,2;//c++11可以直接初始化动态数组了
-
构造临时对象:
class A public: A()=default; A(int a):a_(a) A(int a,int b):a_(a) int a_; ; A func() return 2,3;
三、c++11的初始化列表(std::initializer_list)
c++11扩充了c++98/03的初始化列表,进化成了std中的一个泛型类。在初始化vector等标准库容器时很常喷到它。
但在初始化中,std::initializer_list的出现往往会引起出乎意料的情况:
class A
public:
A()=default;
A(bool a):a_(a)
A(std::initializer_list<int> list):a_(list.size())
int a_;
;
int main()
A aa1(false);
A aa2false;
std::cout<<aa1.a_<<std::endl;
std::cout<<aa2.a_<<std::endl;
以上运行结果:
zkcc@LAPTOP-OHBI7I8S:~/mytest$ g++ test_init.cc -o test_init && ./test_init
0
1
这说明了一个很关键的问题:c++貌似更倾向于将统一初始化写法与std::initializer_list匹配,哪怕另外一条路径有着更匹配的类型。
在上面的代码中, A aa2false;
有2条可能的路径:
1. 将false看成bool型的统一初始化,匹配第一个构造函数
2. 将false强转成std::initializer_list,匹配第二个构造函数
明显感觉第一个构造函数更匹配一些嘛,也不需要强转,但std::initializer_list就是很霸道,哪怕强转也要匹配!
因此,在使用统一初始化的时候,必须注意初始化的类型构造函数中是否有std::initializer_list作为参数的。需要额外注意这一点!
以上是关于c++11 统一初始化的主要内容,如果未能解决你的问题,请参考以下文章
c++11 统一初始化不适用于“g++ -std=c++0x”