在C++中有多种方式可以进行数据拷贝,但它们实现的方式略有不同。
memcpy
memcpy原型如下,其以字节为单位,可以用来拷贝非重合区域。也就是说如果拷贝的源、目的有重合部分的话,结果是undefined,意味着可能偶尔也是对的。但最好不要这么做,原则上memcpy是一种后向拷贝机制:从区间的最后一个元素开始进行拷贝,直到第一个元素。
void* memcpy( void* dest, const void* src, std::size_t count );
memmove
memmove可以支持重合区域的拷贝,其实现可以理解为memmove用另外一块buffer缓存src数据,然后往dst拷贝。但实际上并不是这样,代码在输入时会进行判断:如果src地址小于dst地址,进行后向拷贝;反之如果src地址大于dst,进行前向拷贝。这样就完美的避开了拷贝区间重复而覆盖的问题。
void* memmove( void* dest, const void* src, std::size_t count );
copy/copy_if/copy_n/copy_backward
copy系列函数大部分是C++11支持的模板。原则上是支持重合区域的拷贝,但是是一种『未定义但有效』的方式(undefined but valid),也就是说结果『通常』都是对的,由编译器去实现具体细节,所以不同编译器可能行为上不一致。前面三个都是前向拷贝,最后一个是后向拷贝。也就是说,使用者需要自己去定义:什么时候使用前向拷贝,什么时候使用后向拷贝(参考memmove)。
copy
以下是官网给出的可能的实现机制,从代码实现来说不支持重复区域。
template<class InputIt, class OutputIt>
OutputIt copy(InputIt first, InputIt last,
OutputIt d_first)
{
while (first != last) {
*d_first++ = *first++;
}
return d_first;
}
泛型如下(C++11)
template< class InputIt, class OutputIt >
OutputIt copy( InputIt first, InputIt last, OutputIt d_first );
copy_n
template<class InputIterator, class Size, class OutputIterator>
OutputIterator copy_n (InputIterator first, Size n, OutputIterator result)
{
while (n>0) {
*result = *first;
++result; ++first;
--n;
}
return result;
}
template< class InputIt, class Size, class OutputIt >
OutputIt copy_n( InputIt first, Size count, OutputIt result );
copy_if
template<class InputIt, class OutputIt, class UnaryPredicate>
OutputIt copy_if(InputIt first, InputIt last,
OutputIt d_first, UnaryPredicate pred)
{
while (first != last) {
if (pred(*first))
*d_first++ = *first;
first++;
}
return d_first;
}
template< class InputIt, class OutputIt, class UnaryPredicate >
OutputIt copy_if( InputIt first, InputIt last,
OutputIt d_first,
UnaryPredicate pred );
copy_backward
后向拷贝:
template< class BidirIt1, class BidirIt2 >
BidirIt2 copy_backward(BidirIt1 first, BidirIt1 last, BidirIt2 d_last)
{
while (first != last) {
*(--d_last) = *(--last);
}
return d_last;
}
template< class BidirIt1, class BidirIt2 >
BidirIt2 copy_backward( BidirIt1 first, BidirIt1 last, BidirIt2 d_last );
参考
http://www.cplusplus.com/reference/algorithm/copy_n/
http://en.cppreference.com/w/cpp/string/byte/memmove
http://en.cppreference.com/w/cpp/string/byte/memcpy
http://en.cppreference.com/w/cpp/algorithm/copy
http://en.cppreference.com/w/cpp/algorithm/copy_backward
http://stackoverflow.com/questions/41425865/how-to-move-2-elements-from-head-into-given-position-in-vector
说明
装载请注明出处:http://vinllen.com/memcpy-memmovehe-copy-copyif-copyn-copy_backwardde-qu-bie/