如何将数组的内容附加到 std::vector?

How to append the content of arrays to a std::vector?

我有两个数组

float vertices[] = {
    -0.5f, -0.5f, 0.0f,
     0.5f, -0.5f, 0.0f,
     0.0f,  0.5f, 0.0f
};  

float normals[] = {
    0.0, 0.0f, 1.0f,
     0.0f, 0.0f, 1.0f,
     0.0f,  0.0f, 1.0f
}; 

我首先想将 vertices 数组添加到 std::vector<float>,然后将 normals 数组插入向量。

我能想到的是 运行 基于 sizeof(Array) 的循环并将单个元素推回向量。

当我返回时,是否能保证插入的值顺序正确?

要将元素插入 std::vectorfloat 中,您可以使用 std::copy:

std::vector<float> my_vector;
my_vector.reserve(std::size(vertices) + std::size(normals)); // optional

std::copy(std::begin(vertices), std::end(vertices), std::back_inserter(my_vector));
std::copy(std::begin(normals), std::end(normals), std::back_inserter(my_vector));

my_vector 中的元素顺序与 verticesnormals 中的相同。

Do we need to reserve the memory before inserting the Arrays ?

从技术上讲,没有。但是保留内存可能有助于避免不必要的重新分配。

编辑。

cppreference 中 std::vector::reserveNotes 部分内容如下:

When inserting a range, the range version of insert() is generally preferable as it preserves the correct capacity growth behavior, unlike reserve() followed by a series of push_back()s.

我的回答中的食谱有效,但 JeJo 中的那个应该是首选。

您可以std::vector::insert向量末尾的元素。

#include <iterator> // std::cbegin, std::cend, std::size
#include <vector>
std::vector<float> vec;
// reserve the memory for unwated reallocations.
vec.reserve(std::size(vertices) + std::size(normals));

vec.insert(vec.end(), std::cbegin(vertices), std::cend(vertices));
vec.insert(vec.end(), std::cbegin(normals), std::cend(normals));

[...] running a loop based on the sizeof(Array) and push back individual element to the vector. Would that guarantee that the values inserted are in the correct sequence when I access them back?

是的,的确如此。请记住,您可以使用 std::size to find the size of the array, if you have access to 或更高版本的编译器。

您可能希望将这两个数组追加现有std::vector创建一个新数组其中之一。在这两种情况下,您很可能希望一次保留插入所需的所有内存,以避免额外的不必要的重新分配。

对于前一种情况,可以使用如下函数模板:

template<size_t... Ns>
void append_to_vector(std::vector<float>& vec, float (&...arrs)[Ns]) {
   constexpr auto num_elements_to_append = sizeof...(Ns);
   vec.reserve(vec.size() + num_elements_to_append);
   (vec.insert(vec.end(), std::cbegin(arrs), std::cend(arrs)),...);
}

verticesnormals 附加到现有的 std::vector<float> 变为:

std::vector<float> vec; // your existing vector
// ...
append_to_vector(vec, vertices, normals);

对于后一种情况——即,您想从这两个数组中创建一个新向量——您可以使用以下函数模板,create_vector,它依次调用 append_to_vector

template<size_t... Ns>
std::vector<float> create_vector(float (&...arrs)[Ns]) {
   std::vector<float> vec; 
   append_to_vector(vec, arrs...);
   return vec;
}

从数组 verticesnormals 创建一个新向量归结为一行:

auto vec = create_vector(vertices, normals);

你不限于两个数组。由于它们的 variadic 性质,您实际上可以为这些函数模板提供 任意数量的数组 ,例如:

auto vec = create_vector(vertices, vertices, normals, vertices, normals); 

上面的代码行如您所料,即它创建了一个新向量,该向量由 verticesvertices(再次)、normals 中的元素串联而成verticesnormals.

在任何情况下,对于 append_to_vector() 的每次调用,最多只会执行一次重新分配 因为对 std::vector::reserve() 的调用确保了内存插入新元素所需的元素在插入之前可用。