简体   繁体   English

为什么 std::array 没有一个构造函数来为要填充的数组取值?

[英]Why does std::array not have an constructor that takes a value for the array to be filled with?

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.这对我来说似乎非常有用,并且动态容器(如std::vector )确实有一个类似的构造函数。

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. 根据设计, std::array是一个聚合,因此没有用户声明的构造函数。

As you say, you could use fill after default constructing. 如你所说,你可以在默认构建后使用fill Since it's an aggregate, default construction won't zero the memory, but will leave it uninitialised (if the contained type is trivially initialisable). 由于它是一个聚合,因此默认构造不会将内存归零,但会使其保持未初始化状态(如果包含的类型可以简单地初始化)。

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');

First of all, it is not std::array<T> , it is std::array<T,N> where N is compile time constant integral expression. 首先,它不是std::array<T> ,它是std::array<T,N> ,其中N是编译时常量积分表达式。

Second, std::array is made aggregate by design. 其次, std::array是按设计聚合的。 So it doesn't have anything which makes it non-aggregate, which is why it doesn't have constructor... and destructor, virtual functions, etc. 所以它没有任何使它成为非聚合的东西,这就是为什么它没有构造函数...和析构函数,虚函数等。

You may use std::index sequence for that: 您可以使用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>());
}

Demo 演示

std::make_index_sequence is C++14, but can be implemented in C++11. std::make_index_sequence是C ++ 14,但可以在C ++ 11中实现。

static_cast<void>(Is) is to handle evil operator, that T might provide. static_cast<void>(Is)是处理邪恶的operator, T可能提供。

I took answer from Jarod42 and made an extension to be able to use variable amount of Constructor arguments and also added automatic indexer as a first arg:我从Jarod42 得到了答案并进行了扩展,以便能够使用可变数量的构造函数参数,并添加了自动索引器作为第一个参数:

namespace detail {
  template <typename T, std::size_t... Seq, typename... Args>
  constexpr std::array<T, sizeof...(Seq)> make_array(std::index_sequence<Seq...>, Args &... args)
  {
    return {{(static_cast<void>(Seq), T(Seq, args...))...}};
  }
}  // namespace detail

template <typename T, std::size_t N, typename... Args>
constexpr std::array<T, N> make_array(Args &... args)
{
  return detail::make_array<T>(std::make_index_sequence<N>(), args...);
}

class myClass {
  myClass(unsigned int i, float a, std::string b, int c):... {};
}

Usage:用法:

auto myArray = make_array<myClass, 64>(a, b, c);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM