用一个元素填充构造std::array

Construct std::array by filling with one element

我有一个列表 class,其中大小变量是 const 成员。这对我很有帮助,因为它强制要求列表的大小可以在 运行 运行 之间变化,但不能在单个 运行.

之间变化

我想创建这些列表的集合。集合中列表的数量是一个模板变量,所以我想使用 std::array... 即,我想要一个列表数组,其中数组的大小是一个模板参数,并且每个列表的大小是 const 在构建时指定的

不幸的是:

我知道还有其他选择:

由于其中 none 是完全理想的,我认为如果有一个数组构造函数(或辅助函数)作为参数会很棒:

  1. T的数组元素个数
  2. 单个T对象

...and return a std::array<T> 其中每个 T 都是从参数 2.

复制构造的

有这种东西吗?

std::array<T, N> 是一个模板 class,表示 T 类型元素的长度 N 的数组。如果您想创建列表数组,您只需执行 std::array<std::list<T>>, N>,其中 N 编译时 已知。 const std::size_t N 不够,必须是 constexpr.

所以不,你不能那样做。但是,您可以为此使用 std::vector

如果您 post 努力编写一些代码,我们可以想出更好的东西。

好的。模板魔术。由于std::array是聚合类型,可以使用聚合初始化来初始化:

std::array<T, 5> arr = { one, two, three, four, five };

想法是 one,...,five 是 T 类型(在您的情况下为列表)构造对象的五个副本,使用用户输入作为参数。那么,让我们玩吧。看完这篇不笑不哭:

想法是取一个类型为 T 的对象,并将其复制五次:

 { T(param), .... }; // Five repetitions.

所以,让我们创建一个 return 数组已经初始化的函数:

std::array<A, 5> arr = create_array_by_copy<5>(A(10));

该函数将 return 一个具有 5 个临时对象副本的 array<A, 5>

为此,我们将使用一个辅助 struct,它将创建一个长度为 5 的参数包(参数化为 s):

template<std::size_t s, class... voids_t>
struct sized_pack : public sized_pack<s - 1, voids_t..., void>
{};

template<class... voids_t>
struct sized_pack<0, voids_t...>
{};

这将创建一个名为 voids_t 的参数包,它只是 s void 的列表。现在,技巧的核心:

template<std::size_t s, class T, class... pack_t>
std::array<T, s>
create_array_by_copy_helper(sized_pack<0, pack_t...> const&,
                            T const& o)
{ return { (pack_t(), o)... }; }

template<std::size_t s, class T>
std::array<T, s> create_array_by_copy(T const& o)
{
    return create_array_by_copy_helper<s>(sized_pack<s>(), o);
}

这很复杂。我知道...因为我们已经将 sized_pack<s> 类型的对象传递给辅助函数,该临时对象将实例化 sized_pack 的层次结构,最后一个基数 class 将是类型的对象sized_pack<0, void, void, void, void, void>.

函数 apply 将接收该对象作为对 size_pack<0, pack_t...> 的引用(最后一个基数 class,注意第一个 0),因此,pack_t 将是我们的 5 列表voids.

最后,我们有:

 (pack_t(), o)

这只是逗号运算符,所以,它 returns o。这个想法是我们在 "pattern" 中插入了 pack_t(参数包),因此,当将 ... 应用于表达式时,它将被逗号分隔的表达式替换,其中每个pack_t appearance 会被参数包中的每个元素按相同的顺序替换,所以:

  { (pack_t(), o)... }

转换为:

  { (void(), o), (void(), o), (void(), o), (void(), o), (void(), o) }

一个初始化列表!!最后,每个元素只是一个 void 表达式,后跟逗号运算符,只有每对中的第二个元素将被逗号运算符 returned。因此,评估的表达式将是:

  return { o, o, o, o, o }; // With its corresponding calls to `forward`.

我们想要的初始化列表!!

Coliru 示例:

http://coliru.stacked-crooked.com/a/d6c4ab6c9b203130

您只需将类型 T 替换为您的列表 class。