zoukankan      html  css  js  c++  java
  • C++统一初始化

    1.C++中指定初始化值的方式有4种方式:
    (1)小括号 int x(0);
    (2)等号 int x = 0;
    (3)大括号 int x{0};
    (4)等号和大括号 int x = {0};
    
    2.C++11统一初始化, 即使用大括号初始化方式, 其使用场景主要有以下3种:
    (1)类非静态成员指定默认值
    (2)为容器赋值 vector<int> vec = {1, 2, 3};
    (3)对不支持拷贝操作的对象赋值 unique_ptr<int> p{};
    之所以称为统一初始化, 其原因在于上述3种使用场景中, 
    第(1)种不支持小括号;
    第(2)种不支持等号和小括号;
    第(3)种不支持等号.
    
    3.统一初始化的优势:
    (1)能禁止内置类型之间的隐式窄化转换, 即表达式无法保证接收对象能够表达其值, 则代码不能通过编译(至少会给出编译警告)!double d{}; long x{d};
    (2)可以有效解决小括号定义对象却解析为声明函数的问题.
    如 int x(); 声明为函数 x 而不是定义变量, 使用统一初始化则不会出现问题.
    
    4.统一初始化的不足:
    不足之处在于重载匹配过程变得更加复杂, 难于理解:
    (1)对重载函数, 统一初始化使用大括号会将数据声明为 initializer_list 对象, 
    只有重载匹配过程中, 无法找到 initializer_list类型的形参时, 其它函数才会成为可选函数.
    因此, 对声明了 initializer_list 形参的重载函数, 则使用统一初始化的代码会优先匹配该函数, 而其他更精确匹配的版本可能没有机会被匹配.
    其中需要特别注意的是经常使用容器 vector.
    如 vector<int> vec(10, 2) 和 vector<int> vec{10,2}, 前者是含有 10 个元素的对象, 而后者是只包含 102 两个元素的对象.
    (2)对于构造函数, 空大括号构造一个对象时, 不是匹配 initializer_list 形参的版本, 而是默认构造函数.
    class Test
    {
    public:
        Test()
        {
            PRINT_POS();
        }
        template <typename T>
        Test(std::initializer_list<T> ls)
        {
            Q_UNUSED(ls);
            PRINT_POS();
        }
    };
    进行如下调用时,
      Test t1{};
      Test t2{1};
      // Test t3{{}}; //error: no matching function for call to 'Test::Test(<brace-enclosed initializer list>)'
      Test t4{{1}};
      Test t5({});
    其中 t1 和 t5 使用默认构造函数, t2 和 t4 使用列表初始化构造函数, t3 则不能定义.
    (3)对于 initializer_list 模板特例化版本, 情形较第2种又有所不同.
    a. void foo(int); 
    b. template <typename T>
       void foo(initializer_list<T> lsi);
    当进行以下函数调用 foo(0); foo({}); foo({0}); 时, 分别调用的是 a, a, b.
    c. void foo(int); 
    d. void foo(initializer_list<int> lsi);
    当进行以下函数调用 foo(0); foo({}); foo({0}); 时, 分别调用的是 c, d, d.
  • 相关阅读:
    数据库 Mysql事务详解
    数据库 Mysql内容补充二
    数据库 Mysql内容补充一
    优化Django ORM中的性能问题(含prefetch_related 和 select_related)
    django高级
    百度,谷歌,360,搜狗,神马等蜘蛛IP段
    中国电信、联通、移动、教育IP分布
    sed 给文件每行末尾追加相同字符
    centos7 lvs keepalived做DNS集群负载
    Notepad++ 删除空白行的方法
  • 原文地址:https://www.cnblogs.com/diysoul/p/10426348.html
Copyright © 2011-2022 走看看