2013-04-15 95 views
7

我正在用索引技巧稍微指點一下,看看我能走到哪裏,並遇到一個奇怪的錯誤......首先,簡單的不太舊的索引:意外的非常數std :: initializer_list

template<std::size_t...> 
struct indices {}; 

template<std::size_t N, std::size_t... Indices> 
struct make_indices: 
    make_indices<N-1, N-1, Indices...> 
{}; 

template<std::size_t... Indices> 
struct make_indices<0, Indices...>: 
    indices<Indices...> 
{}; 

我創建從std::initializer_list衍生編譯時數組類,把它轉位(假設N3471是你的編譯器的支持,這將是在未來的標準反正)。那就是:

template<typename T> 
struct array: 
    public std::initializer_list<T> 
{ 
    constexpr array(std::initializer_list<T> values): 
     std::initializer_list<T>(values) 
    {} 

    constexpr auto operator[](std::size_t n) 
     -> T 
    { 
     return this->begin()[n]; 
    } 
}; 

所以,我試圖創建已增加1到每個成員後返回array副本的功能:

template<typename T, std::size_t... I> 
auto constexpr add_one(const array<T>& a, indices<I...>) 
    -> const array<T> 
{ 
    return { (a[I]+1)... }; 
} 

而且隨着代碼來完成,這裏是我的主:

int main() 
{ 
    constexpr array<int> a = { 1, 2, 3 }; 
    constexpr auto b = add_one(a, make_indices<a.size()>()); 

    return 0; 
} 

我沒有想到的是代碼將反正編譯,但我該錯誤消息很驚訝(這裏是ideone代碼):

In function 'int main()': 
error: 'const smath::array<int>{std::initializer_list<int>{((const int*)(& const int [3]{2, 3, 4})), 3u}}' is not a constant expression 

那麼,有人可以向我解釋什麼是不足夠的編譯器在上面的代碼?

編輯:後續處理該問題

+2

A *括號或等號初始值設定項不是一個表達式,並且可以永遠不會是一個常量表達式,這是我認爲的問題。 – Xeo

+0

事實上,Clang 3.2甚至拒絕初始化'a' –

+0

@AndyProwl我知道,Clang不支持N3471,這就是爲什麼:) – Morwenn

回答

0

來源:人類自己 http://www.stroustrup.com/sac10-constexpr.pdf

具體做法是: 它的返回類型,類型它的參數(如果有的話)是文字 類型(見x2.2)。具體來說,文字類型包括bool, int或double; 它的身體是 {return expr; } 其中expr是這樣的,如果用適當類型的任意常量表達式代替expr中的參數,則 的結果表達式是一個常量表達式,如 x2的介紹性段落中所定義。表達式expr被稱爲 潛在的常量表達式。

相關問題