C++ 通过填充一个元素来构造std::array
我有一个list类,其中size变量是C++ 通过填充一个元素来构造std::array,c++,c++11,stdarray,C++,C++11,Stdarray,我有一个list类,其中size变量是const成员。这对我很有帮助,因为它强制要求列表的大小在不同的运行中可能有所不同,但不能在单个运行中有所不同 我想创建这些列表的集合。集合中的列表数是一个模板变量,因此我想使用std::array。。。i、 例如,我想要一个列表数组,其中数组的大小是一个模板参数,每个列表的大小是在构造时指定的const 不幸的是: constsize列表没有默认构造函数(需要指定其大小!),因此我需要为列表的每个元素提供一个构造函数参数。我不能只是创建数组然后设置元素
const
成员。这对我很有帮助,因为它强制要求列表的大小在不同的运行中可能有所不同,但不能在单个运行中有所不同
我想创建这些列表的集合。集合中的列表数是一个模板变量,因此我想使用std::array
。。。i、 例如,我想要一个列表数组,其中数组的大小是一个模板参数,每个列表的大小是在构造时指定的const
不幸的是:
- constsize列表没有默认构造函数(需要指定其大小!),因此我需要为列表的每个元素提供一个构造函数参数。我不能只是创建数组然后设置元素
- 因为我的列表大小是一个模板变量,所以我不能使用标准的初始值设定项列表-所需的元素数量会有所不同
- 我可以使用一个
,然后将元素一个一个地推回std::vector
直到向量的大小等于我的模板参数,但这似乎不美观,因为它不会自然地强制执行这样的条件,即结果向量的大小在完全填充后不应更改
- 我可以翻转索引顺序,得到一个常量大小的
列表。但是,这与我的代码的其余部分不太匹配;我希望能够将单个常量大小的列表从数组传递到客户端代码std::array
- 我可以为常量大小的list类创建一个默认构造函数,创建数组,然后使用placement new逐个替换数组元素。这似乎有一些坏的副作用(const-sized list的默认构造函数是做什么的?如果它在别处被意外调用怎么办?如果我的继任者不知道我做了什么怎么办?)
std::array
,其中每个T
都是从参数2复制构造的
这样的东西存在吗?std::array
是一个模板类,表示T
类型元素的长度为N
的数组。如果要创建列表数组,只需执行std::array,N>
,其中N
在编译时已知<代码>常量std::size\u t N不够,必须如此
所以不,你不能那样做。但是,您可以使用std::vector
进行此操作
如果您发布一些您的工作代码,我们可以想出更好的方法。好的。模板魔术。由于
std::array
是聚合类型,因此可以使用聚合初始化对其进行初始化:
std::array<T, 5> arr = { one, two, three, four, five };
因此,让我们创建一个函数,返回已初始化的数组:
std::array<A, 5> arr = create_array_by_copy<5>(A(10));
这将创建一个名为voids\u t
的参数包,它只是s
void
s的列表。现在,技巧的核心是:
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);
}
它只是逗号运算符,因此返回o
。我们在“模式”中插入了pack\u t
(参数包),因此,当对表达式应用…
时,它将被逗号分隔的表达式替换,其中每个pack\u t
外观将被参数包中的每个元素以相同的顺序替换,因此:
{ (pack_t(), o)... }
转换为:
{ (void(), o), (void(), o), (void(), o), (void(), o), (void(), o) }
初始化列表!!最后,每个元素只是一个后跟coma运算符的void
表达式,逗号运算符只返回每对中的第二个元素。因此,求值表达式将为:
return { o, o, o, o, o }; // With its corresponding calls to `forward`.
我们想要的初始化列表
例如:
您只需要用list类替换类型
T
“每个列表的大小是在构造时指定的常量”-我真诚地希望您也指在编译时,对吗?否则,您可以从一开始就考虑使用std::array
。列表的大小不是编译时常量。谢谢!我认为最简单的方法是存储指向常量大小列表的std::指针数组,然后使用new()创建具有适当大小的列表。我不得不担心新的ing和删除ing,但它保证了我所追求的尺寸possible@user1476176使用智能指针,它自己处理内存分配/释放。你为什么要重新发明std::make_integer_sequence?好的,我不知道它存在。无论如何,它是C++14的一个特性,而且一些编译器版本(如g++4.8.4)至今仍在使用,但还没有完全支持C++14.Cool!我接受这个答案,但你可能也有兴趣看到其他人对我问题的前一个化身给出的答案:我的答案中有一个错误。对象必须通过副本传递,因为不能将同一对象移动五次。这太危险了。我已经简化了解决方案,尽管我知道可以进一步简化。
{ (pack_t(), o)... }
{ (void(), o), (void(), o), (void(), o), (void(), o), (void(), o) }
return { o, o, o, o, o }; // With its corresponding calls to `forward`.