2013-04-15 38 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 

誰かが、上記のコードでコンパイラにとって十分に一定ではないことを私に説明することができますか?

EDIT:その質問についてフォローアップ

+2

* brace-or-equal * initializerは式ではなく、決して定数式ではありません。ここで問題と思われるものです。 – 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は 潜在定数式と呼ばれます。

関連する問題