web-dev-qa-db-ja.com

なぜstd :: arrayには、配列を埋めるための値を取るコンストラクタがないのですか?

の不在は

std::array<T,size>::array(const T& value);

見落とし?それは私にとって非常に便利で、動的コンテナ(std::vector)同様のコンストラクタがあります。

私は完全に知っています

std::array<T,size>::fill(const T& value);

しかし、それはコンストラクタではなく、メモリが最初にゼロにされます。すべてが必要な場合-1のようなもの この男

66
rubenvb

std::arrayは、設計上、集約であるため、ユーザーが宣言したコンストラクタはありません。

あなたが言うように、デフォルトの構築後にfillを使用できます。集約であるため、デフォルトの構築ではメモリがゼロになりませんが、初期化されないままになります(含まれる型が簡単に初期化できる場合)。

49
Mike Seymour

配列がゼロで初期化されておらず、コピーコンストラクターとdoを持っているという事実を利用することで、このタイプのコンストラクターを効率的にシミュレートできることに注意してください。

template <size_t N, class T>
array<T,N> make_array(const T &v) {
    array<T,N> ret;
    ret.fill(v);
    return ret;
}

auto a = make_array<20>('z');
21
tohava

まず、それはstd::array<T>ではなく、std::array<T,N>です。ここで、Nはコンパイル時定数積分式です。

次に、std::arrayは設計により集約されます。そのため、非集約にするものは何もありません。そのため、コンストラクターやデストラクタ、仮想関数などがありません。

11
Nawaz

そのために_std::index sequence_を使用できます:

_namespace detail
{

    template <typename T, std::size_t...Is>
    constexpr std::array<T, sizeof...(Is)>
    make_array(const T& value, std::index_sequence<Is...>)
    {
        return {{(static_cast<void>(Is), value)...}};
    }
}

template <std::size_t N, typename T>
constexpr std::array<T, N> make_array(const T& value)
{
    return detail::make_array(value, std::make_index_sequence<N>());
}
_

デモ

_std::make_index_sequence_はC++ 14ですが、C++ 11で実装できます。

static_cast<void>(Is)は、Tが提供する可能性のある悪__operator,_を処理します。

9
Jarod42