【问题标题】:how to convert std::vector<vector> to void*如何将 std::vector<vector> 转换为 void*
【发布时间】:2016-11-14 17:28:31
【问题描述】:

我想知道如何将std::vector&lt;vector&gt; 转换为void*,例如:

std::vector<ColorData> pixels_ (w*h, background_color);

现在我想将pixels_ 转换为void*,这样我就可以将memcpy 转换为pixels_

memcpy ((void*)destinationBuffer->pixels_, (void*)sourceBuffer->pixels_, \
sizeof(ColorData)*destinationBuffer->width_*destinationBuffer->height_);
 

但是当我运行这段代码时,我收到一条错误消息:

从类型“std::vector<:colordata>”到类型“void*”的无效转换

如何将std::vector&lt;vector&gt; 转换为void*

【问题讨论】:

  • 为什么不定期复制向量呢?如果它是 POD 类型,许多实现将在内部调用 memcpy。这对我来说似乎是一个过早的优化。
  • ... 或 &*sourceBuffer.pixels.begin() 或 &sourceBuffer.pixels.front()。
  • 在 c++11 中,您有 .data() 函数来获取指向基础数据的指针。否则你可以做&amp;vec[0]。但这只是在你真的必须这样做的情况下,因为通常有更好的方法(例如提到的 std::copy)。

标签: c++ stdvector


【解决方案1】:

要将您的向量转换为void* 类型,有两种选择:

  • Pre C++11:(void*)&amp;pixels_[0](推荐!empty()勾选)
  • C++11 起:static_cast&lt;void*&gt;(pixels_.data())

但是,如果您想复制元素,请直接使用 STL 函数:

它们是类型安全的,您的代码看起来更干净,并且在大多数情况下性能将保持一致。此外,与std::memcpy 不同,它还支持非平凡可复制类型(例如std::shared_ptr)。

记住:

我们应该忘记小的效率,比如大约 97% 的时间:过早优化是万恶之源。然而,我们不应该放弃那关键的 3% 的机会

TriviallyCopyable

更新:从 C++17 开始,您还可以使用 std::data,它适用于任何使用连续内存存储的容器(例如 std::vectorstd::stringstd::array)。

ColorData* buffer = std::data(pixels_);

【讨论】:

  • 太棒了!值得一提的是:std::copy() 的性能出乎所有人的意料,即使不优于 memcpy(),至少对于可复制的类型而言。
  • 请注意 &piexls_[0] 要求您有一个非空向量。最好是在复制之前检查是否有任何元素。似乎 .data() 避免了这种情况(以及使用 std::copy)。
  • 谢谢。对于正确的索引,虽然operator[] 不执行任何边界检查,但不进行检查就使用它不是一个好习惯。因为std::copy 不是必需的,因为begin() 将返回一个 past-the-end 迭代器,因此实际上不会复制任何内容。
  • @Christophe 没错。我记得有一个特定情况,使用 std::copy&lt;char*&gt; 比使用 memcpy 更快,因为编译器 (icc) 正在对副本进行矢量化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-31
  • 2020-12-07
  • 2020-07-25
  • 2017-05-13
  • 2016-12-06
  • 2021-03-02
相关资源
最近更新 更多