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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM