如何将数组的内容附加到 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::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));
[...]根据
sizeof(Array)
运行循环并推回 向量的单个元素。这能保证价值观吗 当我重新访问它们时,插入的顺序是否正确?
是的,确实如此。请记住,如果您有权访问 c++17 或更高版本的编译器,则可以使用std::size
来查找数组的大小。
您可能希望将这两个数组追加到现有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)),...);
}
将vertices
和normals
追加到现有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;
}
从数组创建新向量vertices
和normals
归结为一行:
auto vec = create_vector(vertices, normals);
您不限于两个数组。由于它们的可变参数性质,您实际上可以为这些函数模板提供任意数量的数组,例如:
auto vec = create_vector(vertices, vertices, normals, vertices, normals);
上面的行如您所料,即,它创建了一个由vertices
、vertices
(再次(、normals
、vertices
和normals
中的元素串联产生的新向量。
在任何情况下,对于每次调用append_to_vector()
,最多只会执行一次重新分配,因为对std::vector::reserve()
的调用可确保插入新元素所需的内存在插入之前可用。
要将元素插入float
s 的std::vector
中,可以使用 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
中元素的顺序将与vertices
和normals
中的顺序相同。
我们需要在插入数组之前保留内存吗?
从技术上讲,没有。但保留内存可能有助于避免不必要的重新分配。
编辑。
cpp首选项std::vector::reserve
的注释部分如下:
插入范围时,
insert()
的范围版本通常更可取,因为它保留了正确的容量增长行为,这与reserve()
后跟一系列push_back()
不同。
我答案中的食谱有效,但在JeJo的食谱中应该是首选。
- 使用std::vector的OpenCL矩阵乘法
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- std::vector的包装器,使数组的结构看起来像结构的数组
- 编译器如何区分std::vector的构造函数
- 使用 pqxx 将 std::vector 存储在 postgresql 中,并从数据库中检索它
- 在std::vector上存储带有模板的类实例
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 为什么std::vector比数组慢
- std::vector::迭代器是否可以合法地作为指针
- 如何将二进制格式的 C++ 对象的 std::vector 保存到磁盘?
- 为什么std::vector和std::valarray初始化构造函数不同
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 在没有未定义行为的情况下实现类似std::vector的容器
- 如何调整 std::vector of Eigen::MatrixXd 的大小
- 使用 std::vector::reverse_iterator 将 int 序列化为字节向量?
- 如何将AERT_Allocate与 std:vector 一起使用
- 推导 std::vector::back() 的返回类型
- 如何将原始字节附加到 std::vector?
- std::vector 没有重载函数的实例与参数列表匹配
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?