std::copy 是否处理重叠范围?
将数据从一个范围复制到另一个范围时,必须小心源范围和目标范围之间是否存在部分重叠。如果目标范围的开头与源范围的尾部重叠,则纯顺序复制将导致数据出现乱码。除了 memcpy
之外,C 运行时库还具有 memmove
来处理此类重叠问题。
我假设 std::copy 的工作方式与 memcpy 类似,因为它不考虑源区域和目标区域之间的重叠。如果您尝试使用 std::copy
在 std::vector
中“向下”移动对象,则会损坏数据。是否有类似 memmove
的 STL 算法来处理这样的情况?或者我应该使用反向迭代器来推出自己的迭代器?
When copying data from one range to another, you have to be careful if there's partial overlap between the source and destination ranges. If the beginning of the destination range overlaps the tail of the source range, a plain sequential copy will garble the data. The C run-time library has memmove
in addition to memcpy
to handle such overlap problems.
I assume std::copy
works like memcpy
, in that it doesn't pay any regard to overlap between the source and destination regions. If you try to shift objects "down" in a std::vector
with std::copy
, you'll corrupt the data. Is there an STL algorithm analogue of memmove
to handle situations like this? Or should I roll my own with reverse iterators?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果输出范围的开头与输入范围重叠,它不会处理重叠范围。
幸运的是,您可以使用
std::copy_backward
< /a> 相反(这要求您不要将输出范围的末尾与输入范围重叠)。It doesn't handle overlapping ranges if the beginning of the output range overlaps with the input range.
Fortunately, you can use
std::copy_backward
instead (which requires that you don't overlap the end of the output range with the input range).std::copy
的先决条件,禁止重叠:Preconditions for
std::copy
, prohibits an overlap:C++17 标准草案
C+ +17 n4659 标准草案 说:
28.6.1“复制”:
和:
该注释随后解释了何时使用
copy_backward
:因此,不要求这些函数不重叠,并且 与
memcpy
不同,重叠的行为在Effects
中明确定义部分。您只需在它们之间进行选择,因为您通常需要
std::copy
用于向左复制,而std::copy_backward
用于向右复制。C++ 在
中还有一个std::move
的范围版本,它移动而不是复制。C++17 standard draft
The C++17 n4659 standard draft says:
28.6.1 "Copy":
and:
The note then explains when to use
copy_backward
:Therefore, there is no requirement of no overlap for those functions, and unlike for
memcpy
, the behavior of overlaps is clearly defined in theEffects
sections.You just choose between them because you usually want
std::copy
for copying left andstd::copy_backward
for copying right.C++ also has a ranged version of
std::move
in<algorithm>
which moves instead of copying.似乎最直接的方法是创建要复制的范围的临时向量:
您可以将其包装在模板化函数中,该函数应该能够使用任何容器/迭代器类型进行重叠。
It seems the most straight forward way would be to create a temporary vector of the range you want to copy:
You can wrap this in a templated function that should be ably to do an overlapped using any container/iterator type.