问题
Is the absence of
std::array<T,size>::array(const T& value);
an oversight? It seems mighty useful to me, and dynamic containers (like std::vector
) do have a similar constructor.
I am fully aware of
std::array<T,size>::fill(const T& value);
but that is not a constructor, and the memory will be zeroed out first. What if I want all -1
\'s like this guy?
回答1:
std::array
is, by design, an aggregate, so has no user-declared constructors.
As you say, you could use fill
after default constructing. Since it's an aggregate, default construction won't zero the memory, but will leave it uninitialised (if the contained type is trivially initialisable).
回答2:
Note that you can efficiently simulate this type of constructor by taking advantage of the fact that array is not zero-initialized, and has a copy constructor and 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');
回答3:
First of all, it is not std::array<T>
, it is std::array<T,N>
where N
is compile time constant integral expression.
Second, std::array
is made aggregate by design. So it doesn't have anything which makes it non-aggregate, which is why it doesn't have constructor... and destructor, virtual functions, etc.
回答4:
You may use std::index sequence
for that:
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>());
}
Demo
std::make_index_sequence
is C++14, but can be implemented in C++11.
static_cast<void>(Is)
is to handle evil operator,
that T
might provide.
来源:https://stackoverflow.com/questions/17923683/why-does-stdarray-not-have-an-constructor-that-takes-a-value-for-the-array-to