83

是否缺席

std::array<T,size>::array(const T& value);

疏忽?它对我来说似乎很有用,动态容器(如std::vector)确实有一个类似的构造函数。

我完全清楚

std::array<T,size>::fill(const T& value);

但这不是构造函数,内存将首先清零。如果我想要所有人都-1喜欢这个人怎么办?

4

5 回答 5

56

std::array按照设计,它是一个聚合,因此没有用户声明的构造函数。

正如您所说,您可以fill在默认构造之后使用。由于它是一个聚合,默认构造不会将内存归零,但会使其未初始化(如果包含的类型可以轻松初始化)。

于 2013-07-29T12:14:08.830 回答
23

请注意,您可以利用数组不是零初始化的事实有效地模拟这种类型的构造函数,并且具有复制构造函数并执行。

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');
于 2013-07-29T12:16:55.797 回答
15

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

演示

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

static_cast<void>(Is)是处理operator,可能T提供的邪恶。

于 2016-12-21T09:16:54.470 回答
10

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

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

于 2013-07-29T12:14:46.223 回答
0

我从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):... {};
}

用法:

auto myArray = make_array<myClass, 64>(a, b, c);
于 2021-12-02T20:33:10.277 回答