如何从std::vector中直接初始化固定元素数量的std::array(元素无默认构造函数)
Hey there! The tricky part here is that our foo class doesn’t have a default constructor—so we can’t just create an empty std::array and fill it in later. We need to initialize the array with elements from the vector right when we create it.
Here’s a clean, modern way to do this using C++20 template lambdas, which lets us skip writing extra helper functions:
#include <array> #include <vector> #include <utility> // 用于std::index_sequence和std::make_index_sequence class foo { public: foo(int i, float j) : i{i}, j{j} {} private: int i; float j; }; void bar() { std::vector<foo> baz = {{0, 1}, {0, 2}, {0, 3}}; constexpr size_t copyCount = 2; // 核心初始化代码 std::array<foo, copyCount> copiedElements = [&baz]() { // 生成0到copyCount-1的索引序列 return [&]<std::size_t... Is>(std::index_sequence<Is...>) { // 展开索引,直接用vector对应元素初始化array return std::array<foo, copyCount>{baz[Is]...}; }(std::make_index_sequence<copyCount>{}); }(); }
Let me break down what’s going on here:
- We use a lambda to capture the vector
bazby reference, so we can access its elements. - Inside,
*std::make_index_sequence<copyCount>*generates a pack of indices (0 and 1 in this case) matching the number of elements we want to copy. - We expand those indices to pull
baz[0]andbaz[1]from the vector, then initialize thestd::arraywith those elements directly.
If you’re stuck with an older C++ standard (pre-C++20), you can use a helper function instead:
#include <cassert> // 用于断言vector元素数量足够 template <typename T, std::size_t N, std::size_t... Is> std::array<T, N> array_from_vector_impl(const std::vector<T>& vec, std::index_sequence<Is...>) { return {vec[Is]...}; } template <typename T, std::size_t N> std::array<T, N> array_from_vector(const std::vector<T>& vec) { // 一定要确保vector有足够元素,避免越界访问! assert(vec.size() >= N); return array_from_vector_impl<T, N>(vec, std::make_index_sequence<N>{}); } // 在bar()中这样调用: std::array<foo, copyCount> copiedElements = array_from_vector<foo, copyCount>(baz);
A quick critical note: always double-check that your vector has at least copyCount elements before doing this—otherwise you’ll trigger an out-of-bounds access, which is undefined behavior.
内容来源于stack exchange

