假设我有一个编译时已知大小的
到目前为止,我找到的最佳解决方案是:
该应用程序类似于使用非默认构造类型填充std :: array(无可变参数模板):我也有一个不是默认构造的类型,因此我需要在数组初始化时计算实际值。但与那个问题相反,对于我来说,这些值不仅仅是索引函数,还取决于前面的值。我可以使用循环更轻松地构建我的值,而不是一系列函数调用。因此,我在循环中构建元素并将它们放入向量中,然后我想使用该向量的最终状态来初始化数组。
std::vector
,我想把它转换成std::array
。我该怎么做?有没有标准函数可以实现这个功能?到目前为止,我找到的最佳解决方案是:
template<class T, std::size_t N, class Indexable, std::size_t... Indices>
std::array<T, N> to_array_1(const Indexable& indexable, std::index_sequence<Indices...>) {
return {{ indexable[Indices]... }};
}
template<class T, std::size_t N, class Indexable>
std::array<T, N> to_array(const Indexable& indexable) {
return to_array_1<T, N>(indexable, std::make_index_sequence<N>());
}
std::array<Foo, 123> initFoos {
std::vector<Foo> lst;
for (unsigned i = 0; i < 123; ++i)
lst.push_back(getNextFoo(lst));
return to_array<Foo, 123>(lst); // passing lst.begin() works, too
}
该应用程序类似于使用非默认构造类型填充std :: array(无可变参数模板):我也有一个不是默认构造的类型,因此我需要在数组初始化时计算实际值。但与那个问题相反,对于我来说,这些值不仅仅是索引函数,还取决于前面的值。我可以使用循环更轻松地构建我的值,而不是一系列函数调用。因此,我在循环中构建元素并将它们放入向量中,然后我想使用该向量的最终状态来初始化数组。
上述内容似乎编译并正常工作,但也许有改进的方法。
- 也许我可以巧妙地利用一些标准库功能,这是我不知道的。
- 也许我可以以某种方式避免使用帮助函数。
- 也许我可以以某种方式制定这个问题,使其适用于元素的移动语义而不是上面所使用的复制语义。
- 也许我可以避免使用
operator[]
进行随机访问,而只使用前向迭代器语义,这样它也可以适用于std::set
或std::forward_list
作为输入。 - 也许我应该停止使用
std::vector
,而是使用C++17或一些等效实现中的std::array<std::optional<T>, N>
来表达我的目标。
相关问题:
- 请点击拷贝 std::vector 到 std::array,它不假设有默认构造函数的类型,因此在默认初始化之后进行拷贝是可行的,但对我来说不是。
- 请点击使用非默认可构造类型(无可变参数模板)填充 std::array,它独立计算每个元素的索引,因此试图避免中间容器。答案使用可变参数模板,尽管标题要求避免使用它们。
std::array
中的愿望所迫,但相比原始的std::vector
,这有什么优势呢?两者都将数据保存在连续的内存块中,因此前者并没有比后者更具优势。唯一的区别是size
是一个编译时变量,但无论如何都是如此。 - Walterstd::set
,所以我至少需要进行一次转换。而且我还使用了一个转换构造函数来执行元素的类型转换。因此,这不仅仅是保留std::vector
的问题。虽然我可以使用它。主要的反对意见可能是我感觉编译器知道得越多,它就能优化得越好。实际上,我只处理24个元素,尽管这可能对于完全展开循环来说太多了,但它可以例如展开4个元素的组,因为它知道计数可被4整除。这只是一种感觉。 - MvG