如何将std::vector<vector>转换为void*?

17

我想知道如何将 std::vector<vector> 转换为 void*,例如:

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

现在我想要将pixels_转换为void*,以便我可以对pixels_进行memcpy

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

但当我运行这段代码时,出现了以下错误:

从类型 'std::vector<image_tools::ColorData>' 到类型 'void*' 的转换是无效的

我该如何将 std::vector<vector> 转换为 void*


6
为什么不直接定期复制向量呢?如果它是一个 POD 类型,许多实现内部将调用 memcpy。在我看来,这看起来像是一种过早的优化。 - NathanOliver
... 或 &*sourceBuffer.pixels.begin(),或 &sourceBuffer.pixels.front()。 - Martin Bonner supports Monica
3
在 C++11 中,可以使用 .data() 函数获取指向底层数据的指针。否则,您可以使用 &vec[0]。但这只有在确实需要时才能这样做,通常有更好的方式(例如所提到的 std::copy)。 - RyanP
1个回答

27

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

  • C++11 之前:(void*)&pixels_[0] (建议进行 !empty() 检查)
  • C++11 及以后:static_cast<void*>(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() 一样好甚至更好。 - Christophe
1
请注意,&piexls_[0] 要求您拥有一个非空向量。最好在复制之前检查是否有任何元素。似乎 .data() 可以避免这种情况(以及使用 std::copy)。 - Hans Olsson
1
谢谢。对于索引,虽然 operator[] 不执行任何边界检查,但是在使用它时不进行检查并不是一个好习惯。对于 std::copy 来说是不必要的,因为 begin() 将返回一个 past-the-end 迭代器,所以实际上不会复制任何内容。 - Jorge Bellon
1
@Christophe没错。我记得有一个具体的案例,使用std::copy<char*>比使用memcpy更快,因为编译器(icc)会将复制向量化。 - Jorge Bellon
static_cast<void*> 对我很有用。谢谢! - Skyfish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接