2016-08-13 74 views
11

我可以使用std::initializer_list對象而不是大括號初始化程序來初始化數組嗎?我可以初始化一個數組使用std :: initializer_list而不是大括號初始化?

衆所周知,我們可以這樣做:http://en.cppreference.com/w/cpp/language/aggregate_initialization

unsigned char b[5]{"abc"}; 
// equivalent to unsigned char b[5] = {'a', 'b', 'c', '\0', '\0'}; 

int ar[] = {1,2,3}; 
std::array<int, 3> std_ar2{ {1,2,3} }; // std::array is an aggregate 
std::array<int, 3> std_ar1 = {1, 2, 3}; 

但我不能std::initializer_list il;初始化數組:

http://ideone.com/f6aflX

#include <iostream> 
#include <initializer_list> 
#include <array> 

int main() { 

    int arr1[] = { 1, 2, 3 }; // OK 
    std::array<int, 3> arr2 = { 1, 2, 3 }; // OK 

    std::initializer_list<int> il = { 1, 2, 3 }; 
    constexpr std::initializer_list<int> il_constexpr = { 1, 2, 3 }; 

    //int arr3[] = il; // error 
    //int arr4[] = il_constexpr; // error 

    //std::array<int, 3> arr5 = il; // error 
    //std::array<int, 3> arr6 = il_constexpr; // error 

    return 0; 
} 

但我怎麼能使用std::initializer_list il;來初始化一個數組?

+5

複製..「duped」是關於使用'{..}'初始化成員數組的一般問題。這個問題使用'std :: initializer_lists'來初始化'std ::'類型(不允許更改!)。他們是完全不同的問題。 –

+0

@Alex不能使用'algorithm'中的'copy'([示例](https://godbolt.org/g/cKiBNg))? – skypjack

回答

8

其他回答正確的說這是不可能的。但隨着小幫手,你可以得到相當接近

template<typename T, std::size_T N, std::size_t ...Ns> 
std::array<T, N> make_array_impl(
    std::initializer_list<T> t, 
    std::index_sequence<Ns...>) 
{ 
    return std::array<T, N>{ *(t.begin() + Ns) ... }; 
} 

template<typename T, std::size_t N> 
std::array<T, N> make_array(std::initializer_list<T> t) { 
    if(N > t.size()) 
     throw std::out_of_range("that's crazy!"); 
    return make_array_impl<T, N>(t, std::make_index_sequence<N>()); 
} 

如果你是開放更多的變通,可以放進一類這個趕靜態已知長度違規,你傳遞一個支撐初始化列表中的情況下, 。但要注意的是誰讀這段代碼大部分人會前往服務檯

template<typename T, std::size_t N> 
struct ArrayInitializer { 
    template<typename U> struct id { using type = U; }; 
    std::array<T, N> t; 

    template<typename U = std::initializer_list<T>> 
    ArrayInitializer(typename id<U>::type z) 
     :ArrayInitializer(z, std::make_index_sequence<N>()) 
    { 
     if(N > z.size()) 
      throw std::out_of_range("that's crazy!"); 
    } 

    template<typename ...U> 
    ArrayInitializer(U &&... u) 
     :t{ std::forward<U>(u)... } 
    { } 

private: 
    template<std::size_t ...Ns> 
    ArrayInitializer(std::initializer_list<T>& t, 
        std::index_sequence<Ns...>) 
     :t{ *(t.begin() + Ns) ... } 
    { } 
}; 

template<typename T, std::size_t N> 
std::array<T, N> f(ArrayInitializer<T, N> ai) { 
    return std::move(ai.t); 
} 

int main() { 
    f<int, 5>({1, 2, 3, 4, 5}); // OK 
    f<int, 5>({1, 2, 3, 4, 5, 6}); // "too many initializers for array<int, 5>" 

    std::initializer_list<int> il{1, 2, 3, 4, 5}; 
    f<int, 5>(il); // ok 
} 

注意,無論是在回答和「頭臺」盒子頂部的非靜態情況下也只檢查是否你提供太多對於initializer_list的情況,很少有初始化元素和錯誤。如果您爲initializer_list的情況提供了太多的情況,則僅忽略尾隨元素。

+0

謝謝!是的,這兩個示例都可用:http://ideone.com/s0ciUW和http://ideone.com/fbnM6W – Alex

6

據我所知,不,不能初始化std::arraystd::initializer_list

問題是,std::array旨在作爲傳統C風格數組的輕量級替換(包裝器)。所以光是沒有構造函數的,所以只能使用隱式構造函數。

集合初始化(通過隱式構造函數)的構造是可能的,因爲它可能是C風格的數組。

但是std::initializer_list是一類,比集合初始化更復雜。

可以初始化,通過例如std::vectorstd::initializer_list但只因爲有一個明確的構造方法,std::vector,接收一個std::initializer_list。但是std::vector是一個較重的類。

我看到的唯一解決方案是2步驟:(1)構造和(2)std::initializer_list值的副本。類似於

std::array<int, 3> arr5; 

auto ui = 0U; 
auto cit = il.cbegin(); 

while ((ui < arr5.size()) && (cit != il.cend())) 
    arr5[ui++] = *cit++; 

對不起,我的英語不好。

+6

_Bad英語?_你比我的大多數同事寫得更好。你不需要像堆棧溢出回答或問題那樣的評論。社區將編輯任何不可理解的內容。 –

+1

@ AndonM.Coleman - 謝謝;我會盡量忽略我的語言不安全感。 – max66

2

std::array的問題是它需要是聚合類型,因此它沒有構造函數。

因此只有聚合初始化或微不足道的複製是可能的。 std::initializer_liststd::array以外的類,因此需要(缺失)隱式轉換。

參見http://en.cppreference.com/w/cpp/language/aggregate_initializationhttp://en.cppreference.com/w/cpp/container/array 僅供參考。

+0

[POD的哪個具體要求禁止這個?](http://coliru.stacked-crooked.com/a/d332ff1ce89c8817) – chris

+0

@chris:抱歉,不是* POD *,而是* Aggregate *類型。 請參閱 http://en.cppreference.com/w/cpp/language/aggregate_initialization和 http://en.cppreference.com/w/cpp/container/array。 剛修復文字 –

相關問題