8

どこに行くことができるかを確認するためにインデックスのトリックを少しいじっていたところ、奇妙なエラーに遭遇しました...まず、それほど古くない単純なインデックス:

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...>
{};

a から派生したコンパイル時配列クラスを作成し、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];
    }
};

arrayそこで、各メンバーに 1 を追加した後に an のコピーを返す関数を作成しようとしました。

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;
}

とにかくコードがコンパイルされるとは思いませんでしたが、エラーメッセージに非常に驚いています (ここにイデオンコードがあります):

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

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

編集:その質問のフォローアップ

4

1 に答える 1

1

From: 本人 http://www.stroustrup.com/sac10-constexpr.pdf

具体的には、その戻り値の型とそのパラメーターの型 (存在する場合) は、リテラル型です (x2.2 を参照)。具体的には、リテラル型には bool、int、または double が含まれます。その本体は、{ return expr; という形式の複合ステートメントです。ここで、expr は、適切な型の任意の定数式が expr のパラメーターに置き換えられる場合、結果の式は、x2 の導入段落で定義されている定数式になります。式 expr は潜在定数式と呼ばれます。

于 2013-06-14T00:22:12.020 に答える