Initializing a std::array with a constant value

2020-02-26 15:05发布

I need to initialize all elements of a std::array with a constant value, like it can be done with 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
}

Is there a way to do this elegantly?

Right now I'm using this:

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

but I'd like to avoid using explicit code for the initialisation.

5条回答
家丑人穷心不美
2楼-- · 2020-02-26 15:19

With std::index_sequence, you might do:

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

With usage

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

Which, contrary to std::fill solution, handle non default constructible type.

查看更多
干净又极端
3楼-- · 2020-02-26 15:29

You can do as following

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

Or use std::fill from algorithms header file. To include algorithms header file use

#include <algorithm>
查看更多
\"骚年 ilove
4楼-- · 2020-02-26 15:33

Since C++17 you can write a constexpr function to efficiently set up the array, since the element accessors are constexpr now. This method will also work for various other schemes of setting up initial values:

#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);
}
查看更多
虎瘦雄心在
5楼-- · 2020-02-26 15:37

The std::array type is an aggregate that supports list-initialization:

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

It also supports aggregate-initialization:

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

This is inconvenient and error-prone for long arrays, and you would be better off using a solution like Jarod42’s for those.

查看更多
Evening l夕情丶
6楼-- · 2020-02-26 15:39

Alas not; std::array supports aggregate initialisation but that's not enough here.

Fortunately you can use std::fill, or even std::array<T,N>::fill, which, from C++20 is elegant as the latter becomes constexpr.

Reference: https://en.cppreference.com/w/cpp/container/array/fill

查看更多
登录 后发表回答