std::vector<float> to std::vector<glm::vecX>无需复制
std::vector<float> to std::vector<glm::vecX> without copying
我正在编写一个小型玩具游戏引擎,使用Tinyobjloader加载.obj文件。我使用glm::vecX存储顶点数据和所有内容,以使事情变得更容易。
当我想要std::vector<glm::vecX>
时,Tinyobjloader会给我一个std::vector<float>
。如果不复制,我该怎么做?
需要明确的是,glm::vecX
是一个简单的结构,例如包含float
成员x, y, z
。
我在想,既然structs的行为有点像数组,那么std::move会起作用,但运气不好。
谢谢!
编辑:我知道我不清楚这件事,对不起。我想将std::vector<float>
移动到std::vector<glm::vecX>
中,或者将其作为std::vector<glm::vecX>&
传递。
使用std::memcpy
复制数据很好,但它会复制数据,我希望避免这种情况。
可以直接将向量的内容解释为结构的实例,而无需复制数据。如果你能保证表示是兼容的,也就是说。vector<float>
的内容在内存中被布置为一个浮动值序列,这些值直接跟在一起(一个数组),没有额外的填充,而vector<glm::vecX>
的内容则被布置为vecX序列。因此,您需要确保以下条件成立:
glm::vecX
正好是X浮点的大小,没有填充。根据结构的声明,这可能与平台有关vector<float>
的内容在正确的序列中,即对于vec3为[x1,y1,z1,x2,y2,z2,…],而不是[x1,x2,…,xN,y1、y2…]
在这种情况下,您可以安全地将浮点向量的数据指针重新解释为指向vecX数组的指针,如本例所示:
std::vector<float> myObjData = ...;
auto nVecs = myObjData.size() / 3; // You should check that there are no remainders!
glm::vec3* vecs = reinterpret_cast<glm::vec3*>(myObjData.data());
std::cout << vecs[0]; // Use vecs[0..nVecs-1]
然而,您无法安全地将向量本身重新解释为glm::vecX的向量,甚至不能重新解释为const向量 然而,大多数时候,您不需要传递实际的向量,因为标准库中的大多数函数都接受容器范围。对于第一个示例中的数组,这很容易给出。所以,如果你想根据z位置对vec3数组进行排序,然后打印出来,你可以这样做:// Don't do this, the result of .size() and .end() may be wrong!
const std::vector<glm::vec3>& bad = *reinterpret_cast<std::vector<glm::vec3>*>(&myObjData);
bad[bad.size()-1].z = 0; // Potential BOOM!
// nVecs and vecs from the first example
std::sort(vecs, vecs+nVecs, // Sort by Z position
[](const glm::vec3& a, const glm::vec3& b) { return a.z < b.z; });
std::copy(vecs, vecs+nVecs, std::ostream_iterator<glm::vec3>(std::cout, "n"));
简而言之:据我所知,不复制是不可能的。
在我看来,std::memcpy
与std::vector
没有任何关系。
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 是std :: set&lt; std :: future&gt;不可能存在
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- 使用 std::vector<boost::shared_ptr<Base_Class>> 或 boost::p tr_vector 的性能注意事项是什么<Base>
- std::map<std::set, double> AND std:<long>map< std::p air<long, long>, double>
- 如何获取std::vector<DMatch>