2012-12-06 128 views
0

隨着函數採取的std :: initializer_list作爲參數的功能像下面所示傳遞原始陣列的std :: initializer_list參數

int sumOf(std::initializer_list<int> numbers) { 
    int sum = 0; 
    for (auto x : numbers) { 
     sum += x; 
    } 
    return sum; 
} 

此代碼的工作

auto sum = sumOf({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });

但不是這

int i[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
auto x = sumOf(i); 

爲什麼第二種形式n工作嗎?或者我做錯了什麼?

編輯:
從GCC 4.7.2執行的std :: intializer_list的,intializer_list的構造函數是私有和編譯器需要通過數組的大小。

// The compiler can call a private constructor. 
    constexpr initializer_list(const_iterator __a, size_type __l) 
    : _M_array(__a), _M_len(__l) { } 

我猜在某些情況下,編譯器無法從變量「i」判斷數組的大小。如果是這樣,編譯器(?)不支持將靜態數組傳遞給intializer_list。

+0

但是'{0,1,2,3,4,5,6,7,8,9,10}'確實創建了一個'std :: initializer_list'。 – kennytm

+1

那麼,通過一個初始化器列表,除了該函數,其他通過和數組,還有什麼應該發生。初始化列表不僅僅是一個數組。把它改成'auto i = {...};',不知道這是否有效。 –

+0

@ChristianRau - 它適用於'auto i = {...};'但是「i」似乎不再是一個int數組。 –

回答

2

i不是initializer_listinitializer_list不是「靜態數組」的簡寫。這是一個特殊的對象,只能通過使用braced-init-list(即:{...}語法)創建(在複製構造之外)。

當你做int i[] = {...};你正在陣列上執行聚合初始化。 iint的數組,而不是initializer_list

你想要的是一個模板函數,可以採取任何你可以使用基於換範圍-過來:

template<typename Rng> 
int sumOf(const Rng &numberRange) { 
    int sum = 0; 
    for (auto x : numberRange) { 
     sum += x; 
    } 
    return sum; 
} 
+0

直接使用'{...}'語法傳遞值時,模板版本不起作用,除非您有專門版本的sumOf(),它需要std :: initializer_list –

+0

@KiranMohan:目前,這是正確的,自動「和正常的模板參數演繹。不過,有一個建議是在C++ Next中修復的。 – Xeo

1

你可以做索引記錄伎倆,如

之前被很多人
template<int N, int ...X> 
struct I : struct I<N-1, N, X...> {}; 

template<int X...> 
struct I<0, X...> { 
    typedef I type; 
}; 

template<typename F, typename T, int N, int ...X> 
decltype(f(std::declval<std::initializer_list<T>>())) 
make_list(T const (&a)[N], F f, I<X...>) 
{ 
    return f(std::initializer_list<T>{a[X]...}); 
} 

template<typename F, typename T, int N> 
decltype(f(std::declval<std::initializer_list<T>>())) 
make_list(T const(&a)[N], F f) { 
    return make_list(a, f, typename I<N-1>::type()); 
} 

用法很容易

make_list(i, &sumOf); 

或使用拉姆達

make_list(i, [](std::initializer_list<int> x) { 
    return sumOf(x); 
}); 
相關問題