我有一个列表类,其中size变量是const
成员。这对我很有帮助,因为它强制要求列表的大小可能因运行而异,但在单个运行中不能有所不同。
我想创建这些列表的集合。集合中的列表数量是模板变量,所以我想使用std::array
...即,我想要一个列表数组,其中数组的大小是模板参数,每个列表的大小是在构造中指定的const
不幸的是:
我认识到有其他选择:
std::vector
和push_back
个元素,直到向量的大小等于我的模板参数,但这似乎不优雅,因为它不会自然地强制执行条件在完全填充后,不应更改生成的矢量大小。std::arrays
列表。但是,这并不适合我的其余代码;我希望能够将数组中的单个const大小的列表传递给客户端代码由于这些都不是完全理想的,我认为如果有一个数组构造函数(或辅助函数)可以作为参数:
...并返回std::array<T>
,其中每个T
都是从参数2复制构造的。
这样的事情存在吗?
答案 0 :(得分:2)
确定。模板魔术。由于std::array
是聚合类型,因此可以使用聚合初始化来初始化它:
std::array<T, 5> arr = { one, two, three, four, five };
这个想法是one
,...,five
是T类型构造对象的五个副本(在您的情况下为list),使用用户输入作为参数。所以,让我们玩吧。读完之后不要笑或哭:
我们的想法是获取一个T类型的对象,并将其复制五次:
{ T(param), .... }; // Five repetitions.
因此,让我们创建一个返回已经初始化的数组的函数:
std::array<A, 5> arr = create_array_by_copy<5>(A(10));
该函数将返回array<A, 5>
个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
的层次结构,其最后一个基类将是{{1}类型的对象}。
函数apply将接收该对象作为sized_pack<0, void, void, void, void, void>
的引用(最后一个基类,注意前0),因此,size_pack<0, pack_t...>
将是我们的5 pack_t
个列表
最后,我们有:
void
只是逗号运算符,因此返回 (pack_t(), o)
。我们的想法是我们在“模式”中插入了o
(参数包),因此,当将pack_t
应用于表达式时,它将被逗号分隔的表达式替换,其中每个...
1}}外观将由参数包中的每个元素以相同的顺序替换,因此:
pack_t
转换为:
{ (pack_t(), o)... }
初始化列表!!最后,每个元素只是一个 { (void(), o), (void(), o), (void(), o), (void(), o), (void(), o) }
表达式,后跟逗号运算符,每个对的第二个元素将由逗号运算符返回。因此,评估的表达式将是:
void
我们想要的初始化列表!!
Coliru例子:
http://coliru.stacked-crooked.com/a/d6c4ab6c9b203130
您只需要将类型 return { o, o, o, o, o }; // With its corresponding calls to `forward`.
替换为列表类。
答案 1 :(得分:0)
std::array<T, N>
是一个模板类,表示N
类型元素的长度为T
的数组。如果要创建列表数组,只需执行std::array<std::list<T>>, N>
,其中N
在编译时已知。 const std::size_t N
是不够的,必须是constexpr
。
所以不,你不能这样做。但是,您可以使用std::vector
。
如果您发布了一些代码,我们可以提出更好的建议。