zoukankan      html  css  js  c++  java
  • C++11中新特性之:initializer_list详解

    C++11提供的新类型,定义在<initializer_list>头文件中。

    template< class T >
    class initializer_list;

    先说它的用处吧,然后再详细介绍一下。

    首先有了initializer_list之后,对于STL的container的初始化就方便多了,比如以前初始化一个vector需要这样:

    int a[] = {0, 1, 2, 3};
    std::vector<int> vec(a, a+sizeof(a));

    或者

    std::vector<int> vec;
    vec.push_back(1);
    vec.push_back(3);
    vec.push_back(3);
    vec.push_back(2);

    有了initializer_list后,就可以直接像初始化数组一样:

    class Test {
    
    private:
        static std::map<string, string> const nameToBirthday = {
            {"lisi", "18841011"},
            {"zhangsan", "18850123"},
            {"wangwu", "18870908"},
            {"zhaoliu", "18810316"},
        };
    }

    当然啦,里面的std::map必须提供参数为initializer_list的构造函数如:

    map( std::initializer_list<value_type> init,
         const Compare& comp = Compare(),
         const Allocator& alloc = Allocator() );

    其实for(initializer: list)中如果list是个形如:{a, b, c...},那么其实list自动被构造成了initializer_list对象。

    下面稍微介绍一下initializer_list

    一个initializer_list当出现在以下两种情况的被自动构造:

    1. 当初始化的时候使用的是大括号初始化,被自动构造。包括函数调用时和赋值
    2. 当涉及到for(initializer: list),list被自动构造成initializer_list对象

    也就是说initializer_list对象只能用大括号{}初始化。

    拷贝一个initializer_list对象并不会拷贝里面的元素。其实只是引用而已。而且里面的元素全部都是const的。

    下面一个例子可以帮助我们更好的理解如何使用initializer_list:

    #include <iostream>
    #include <vector>
    #include <initializer_list>
    
    using namespace std;
    
    template <class T>
    struct S {
        vector<T> v;
        S(initializer_list<T> l) : v(l){
            cout << "constructed with a " << l.size() << "-elements lists" << endl;
        }
        void append(std::initializer_list<T> l) {
            v.insert(v.end(), l.begin(), l.end());
        }
    
        pair<const T*, size_t> c_arr() const{
            return {&v[0], v.size()};
        }
    
    };
    
    
    template <typename T>
    void templated_fn(T arg) {
        for (auto a : arg)
            cout << a << " ";
        cout << endl;
    }
    
    int main() {
        S<int> s = {1, 2, 3, 4, 5}; //automatically construct a initializer_list 
                                    // object and copy it
        s.append({6, 7 , 8});         //list-initialization in function call
    
        cout << "The vector size is now " << s.c_arr().second << " ints:" << endl;
    
        for (auto n : s.v)
            cout << ' ' << n;
        cout << endl;
    
        cout << "range-for over brace-init-list: " << endl;
        
        for (auto x : {-1, -2, 03})   //// the rule for auto makes this ranged for work
            cout << x << " ";
        cout << endl;
    
        auto al = {10, 11, 12};  //special rule for auto
    
        cout << "The list bound to auto has size() = " << al.size() << endl;
    
    
        //templated_fn({1, 2, 3});   //compiler error! "{1, 2, 3}" is not an expressionit has no type, and so T cannot be duduced.
    
        templated_fn<initializer_list<int> > ({7, 8, 9}); //ok
        templated_fn<vector<int> >({3, 5, 7});           //also ok
    
        return 0;
    }

    Reference:

    http://en.cppreference.com/w/cpp/utility/initializer_list

    http://www.cppblog.com/liyiwen/archive/2009/07/26/91248.html

  • 相关阅读:
    Azure PowerShell (2) 修改Azure订阅名称
    Windows Azure Platform Introduction (11) 了解Org ID、Windows Azure订阅、账户
    Azure PowerShell (3) 上传证书
    Azure PowerShell (1) PowerShell入门
    Windows Azure Service Bus (2) 队列(Queue)入门
    Windows Azure Service Bus (1) 基础
    Windows Azure Cloud Service (10) Role的生命周期
    Windows Azure Cloud Service (36) 在Azure Cloud Service配置SSL证书
    Android studio 使用心得(一)—android studio快速掌握快捷键
    android 签名、混淆打包
  • 原文地址:https://www.cnblogs.com/lysuns/p/4278589.html
Copyright © 2011-2022 走看看