zoukankan      html  css  js  c++  java
  • Initializer List

    红色
    绿色
    蓝色

    Initializer List

    An initializer list forces so-called value initialization, which means that even local variables of fundamental types, which usually have an undefined initial value, are initialized by zero(or nullptr, if it is a pointer).

    int i;              //i has undefined value
    int j{};            //j is initialized by 0
    int *p;             //p has undefined value
    int *q{};           //q is initialized by nullptr
    

    Note, however, that narrowing initializations----those that reduce precision or where the value gets modified ---- are not possible with braces. For example:

    int x1(5.3);                            //OK, but x1 becomes 5
    int x2 = 5.3                            //OK, but x2 becomes 5
    int x3{5.0};                            //error:narrowing
    int x4 = {5.3};               //error:narrowing; [warning] narrowing on gcc
    char c1{7};            //Ok. even though 7 is an int, this is not narrowing
    char c2{99999};        //error:narrowing (99999 does't fit into a char)
    std::vector<int> v1 {1, 2, 3, 4};       //OK
    std::vector<int> v2 {1, 2.3, 4, 5.6};   //error:narrowing
    

    initializer_list<>

    To support the concept of initializer lists for user-defined types, C++11 provides the class template std::initializer_list<>. It can be used to support initialization by a list of values or in any other place where you want to process just a list of value. For example:

    void print(std::initializer_list<int> vals){
        for(auto p = vals.begin(); p != vals.end(); p++){
            std::cout << *p << "
    ";
        }
    }       // 传给 initializer_list 的东西一定必须也是个 initializer list 或是一个 a list of values
    print({12, 2, 3, 4, 5}); //pass a list of value to print()
    

    When there are constructors for both a specific number of arguments and an initializer list, the version with the initialier list is preferred. For example:

    class P{
    public:
        P(int a, int b){
            cout << "P(int, int), a=" << a << ", b=" << b << endl;
        }
    
        P(std::initializer_list<int> initlist){
            cout << "P(initializer_list<int>), values=";
            for(auto i : initlist){
                cout << i << endl;
            }
            cout << endl;
        }
    };
    
    P p(77, 5);         //P(int, int), a=77, b=5
    P q{77, 5};         //P(initializer_list<int>), values= 77 5
    P r{77,5,42};       //P(initializer_list<int>), values= 77 5 42
    P s={77,5};         //P(initializer_list<int>), values= 77 5
    

    Without the constructor for the initializer list, the constructor taking two ints would be called to initialize q and s, while the initialization of r would be invalid.

    initializer_list source code


      1. constexper 关键字:const并未区分出编译期常量和运行期常量, constexpr限定在了编译期常量。
      1. noexcept 关键字:该关键字告诉编译器,函数中不会发生异常,这有利于编译器对程序做更多的优化。如果在运行时,noexecpt函数向外抛出了异常(如果函数内部捕捉了异常并完成处理,这种情况不算抛出异常),程序会直接终止,调用std::terminate()函数,该函数内部会调用std::abort()终止程序。

    template<class _E>
    class initializer_list{
    public:
        typedef _E              value_type;
        typedef const _E&       reference;
        typedef const _E&       const_reference;
        typedef size_t          size_type;
        typedef const _E*       iterator;
        typedef const _E*       const_iterator;
    
    private:
        iterator    _M_array;
        size_type   _M_len;
    
        // the compiler can call a private constructor.
        constexper initializer_list(const_iterator __a, size_type __l)
            : _M_array(__a), _M_len(__l) { }
    
    public:
        constexper initializer_list() noexcept
            : _M_array(0), _M_len(0) { }
    
        //Number of elements.
        constexper size_type
        size() const noexcept { return _M_len; }
    
        // First element.
        constexper const_iterator
        begin() const noexcept {return _M_array; }
    
        // One past the last element.
        constexper const_iterator
        end() const noexcept { return begin() + _M_array; }
    }
    

    新版本的 min、max 用到了 initializer_list

    cout << max({ 54, 16, 48, 5 }); //54
    cout << min({ 54, 16, 48, 5 }); //5
    cout << max({ string("Ace", string("Stacy"), string("Barkley"))}); //Ace
    cout << min({ string("Ace", string("Stacy"), string("Barkley"))}); //Stacy
    
    
    template<typename _Tp>
    inline _Tp
    max(std::initializer_list<_Tp> __l){
        return *std::max_element(__l.begin(), __l.end());
    }
    
    template<typename _Tp>
    inline _Tp
    min(std::initializer_list<_Tp> __l){
        return *std::min_element(__l.begin(), __l.end());
    }
    
  • 相关阅读:
    Stack源码分析
    LinkedList源码分析 (JDK1.8)
    AbstractSequentialList源码分析
    Vector源码分析
    ArrayList简介
    获取类运行
    类加载器的作用
    什么时候会发生类初始化
    IIS无法加载字体文件(*.woff,*.svg)的解决办法
    PowerDesigner 显示name(中文) 和显示code(字段名) 设置
  • 原文地址:https://www.cnblogs.com/Codroc/p/13998415.html
Copyright © 2011-2022 走看看