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

rub*_*nvb 72 c++ c++11 stdarray

是没有

std::array<T,size>::array(const T& value);
Run Code Online (Sandbox Code Playgroud)

疏忽?它似乎对我有用,而动态容器(如std::vector)确实有类似的构造函数.

我完全清楚

std::array<T,size>::fill(const T& value);
Run Code Online (Sandbox Code Playgroud)

但这不是构造函数,内存将首先归零.如果我想什么都-1好像这个家伙

Mik*_*our 52

std::array 通过设计,是一个聚合,因此没有用户声明的构造函数.

如你所说,你可以fill在默认构建之后使用.由于它是一个聚合,因此默认构造不会将内存归零,但会使其保持未初始化状态(如果包含的类型可以简单地初始化).

  • 默认初始化对于POD是no-init,对于我认为的其他一切都是默认构造函数 - 取决于声明的要点. (11认同)
  • @rubenvb原始类型都具有普通的默认初始化.如果需要,用户定义的类型可以以相同的方式运行.这不是区别,而是一致性. (10认同)

toh*_*ava 21

请注意,您可以通过利用数组未初始化为零的事实来高效地模拟这种类型的构造函数,并且具有复制构造函数.

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');
Run Code Online (Sandbox Code Playgroud)

  • 可以推断出`char`,所以你可以写`make_array <20>('z')`而不是`make_array <20,char>('z')` (4认同)
  • 当`T`不能默认构造时,这是行不通的,那是您非常需要fill构造函数的时候。 (2认同)

Naw*_*waz 11

首先,它不是std::array<T>,它在std::array<T,N>哪里N是编译时常量积分表达式.

其次,std::array是按设计聚合的.所以它没有任何使它成为非聚合的东西,这就是为什么它没有构造函数...和析构函数,虚函数等.


Jar*_*d42 9

您可以使用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>());
}
Run Code Online (Sandbox Code Playgroud)

演示

std::make_index_sequence 是C++ 14,但可以在C++ 11中实现.

  • 这是最有用的答案,它也适用于`T`不是默认可构造的,也就是当其他答案不足时. (3认同)
  • @MichałBrzozowski:您仍然可以在循环中切换到“std::vector”、“reserve”整个大小和“emplace_back”。对于一百万个元素,堆栈会出现问题,因为实践中内存有限。 (2认同)