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 统一初始化

c++11 统一初始化

c++11 统一初始化不适用于“g++ -std=c++0x”

C++11新特性统一初始化

C++11新特性:11—— C++11列表初始化(统一了初始化方式)

C++11新特性:19—— C++11列表初始化(统一了初始化方式)