web-dev-qa-db-ja.com

定数値でstd :: arrayを初期化する

std::arrayで実行できるように、std::vectorのすべての要素を定数値で初期化する必要があります。

#include <vector>
#include <array>

int main()
{
  std::vector<int> v(10, 7);    // OK
  std::array<int, 10> a(7);     // does not compile, pretty frustrating
}

これをエレガントに行う方法はありますか?

今私はこれを使っています:

std::array<int, 10> a;
for (auto & v : a)
  v = 7;

しかし、初期化に明示的なコードを使用しないようにしたいと思います。

24
Jabberwocky

std::index_sequenceを使用すると、次のことができます。

namespace detail
{
    template <typename T, std::size_t ... Is>
    constexpr std::array<T, sizeof...(Is)>
    create_array(T value, std::index_sequence<Is...>)
    {
        // cast Is to void to remove the warning: unused value
        return {{(static_cast<void>(Is), value)...}};
    }
}

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

使用あり

auto a = create_array<10 /*, int*/>(7); // auto is std::array<int, 10>

std::fillソリューションとは逆に、デフォルト以外の構成可能な型を処理します。

21
Jarod42

残念ながらそうではありません。 std::array集約初期化をサポートしていますが、ここでは十分ではありません。

幸いにもstd::fill、 あるいは std::array<T,N>::fill、後者はconstexprになるため、C++ 20からエレガントです

リファレンス: https://en.cppreference.com/w/cpp/container/array/fill

20
Bathsheba

あなたは次のようにすることができます

std::array<int, 10> a; 
a.fill(2/*or any other value*/);

またはstd::fillアルゴリズムヘッダーファイルから。アルゴリズムヘッダーファイルの使用を含めるには

#include <algorithm>
12
h4ckthepl4net

C++ 17以降では、要素アクセサーがconstexprになっているため、配列を効率的に設定するconstexpr関数を記述できます。この方法は、初期値を設定する他のさまざまなスキームでも機能します。

#include <array>

template<typename T, size_t N>
constexpr auto make_array(T value) -> std::array<T, N>
{
    std::array<T, N> a{};
    for (auto& x : a)
        x = value;
    return a;
}

int main()
{
    auto arr = make_array<int, 10>(7);
}
2
M.M

std::arrayタイプは、リストの初期化をサポートする集合体です:

std::array<int, 10> a{2, 2, 2, 2, 2, 2, 2, 2, 2, 2};

また、集約の初期化もサポートしています。

std::array<int, 10> a = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2};

これは長いアレイでは不便でエラーが発生しやすいので、Jarod42のようなソリューションを使用することをお勧めします。

0
Davislor