看到有人在用std::copy这个东西,很简洁和爽啊,,所以找些帖子学习学习

http://blog.sina.com.cn/s/blog_8655aeca0100t6qe.html

https://www.so.com/s?q=std%3A%3Acopy%E5%87%BD%E6%95%B0&ie=utf-8&src=se7_newtab_new

copy函数的函数原型:

 //fist [IN]: 要拷贝元素的首地址
//last [IN]:要拷贝元素的最后一个元素的下一个地址
//x [OUT] : 拷贝的目的地的首地址 template<class InIt, class OutIt>
OutIt copy(InIt first, InIt last, OutIt x);

如果要把一个序列(sequence)拷贝到一个容器(container)中去,通常用std::copy算法,代码如下:std::copy(start, end, std::back_inserter(container));

这里,start和end是输入序列(假设有N各元素)的迭代器(iterator)[例如start = iterator.begin(); end = iterator.end()],container是一个容器[例如vector],该容器的接口包含函数push_back

假设container开始是空的,那么copy完毕后它就包含N个元素,并且顺序与原来队列中的元素顺序一样。标准库提供的back_inserter模板函数很方便,因为它为container返回一个back_insert_iterator迭代器,这样,复制的元素都被追加到container的末尾了。

现在假设container开始非空(例如:container必须在循环中反复被使用好几次)。那么,要达到原来的目标,必须先调用clear函数然后才能插入新序列。这会导致旧的元素对象被析构,新添加进来的被构造。不仅如此,container自身使用的动态内存也会被释放然后又创建,就像list,map,set的节点。某些vector的实现在调用clear的时候甚至会释放所有内存。

通常,考虑到在一个已有的元素上直接copy覆盖更高效。keyi这样做:

std::copy(start, end, container.begin());

在这里你在container的头部执行了copy-over(覆盖赋值)操作,但是,如果container的大小小于输入序列的长度N的话,这段代码会导致崩溃(crash)

eg1:       //可以使用copy给数组赋值啊!!!   但是要注意  sizeof(b)  必须大于  [(a+3) - (a)] 的长度

int a[3]={1,2,3};

int b[3];
   std::copy(a,(a+3),b);   ------>[a, a+3)
   for(int j=0;j<3;j++)
     cout<<b[j]

eg2:

vector<int> temp(3);  //初始化一个有3个元素的vector
 int a[3]={1,2,3};

std::copy(a,a+3,&temp.front());   // 或者是  std::copy(a, a+3, temp.begin())也可以
 cout<<<endl;
 for(int j=0;j < temp.size(); j++)
  cout<<temp[j];
copy只负责复制,不负责申请空间,所以复制前必须有足够的空间

copy只负责复制,不负责申请空间,所以复制前必须有足够的空间

copy只负责复制,不负责申请空间,所以复制前必须有足够的空间

copy只负责复制,不负责申请空间,所以复制前必须有足够的空间

 

接下来,让我们来看看数组之间直接用for拷贝和用copy拷贝的效率比较http://blog.csdn.net/zhouxuguang236/article/details/10834567

在C++编程中,经常会配到数据的拷贝,如数组之间元素的拷贝,一般的人可能都会用for循环逐个元素进行拷贝,在数据量不大的情况下还可以,如果数据量比较大,那么效率会比较地下。而STL中就提供了一个专门用来进行容器元素拷贝的函数copy

 #include<iostream>
#include<vector>
#include<sys/time.h>
#include<time.h>
#include<iosfwd>
#include<algorithm>
#include<stdio.h> using namespace std; const long SECOND_IN_NS = ; //1second in nanoseconds class Timer //计算时间差的类
{
private:
struct timespec m_start;
struct timespec m_end;
clockid_t m_clockId;
public:
Timer(){
init(true, true);
} Timer(bool realTime){
init(realTime, true);
} Timer(bool realTime, bool startImmediately){
init(realTime, startImmediately);
} void init(bool realTime, bool startImmediately){
if (realTime){
//Real time
m_clockId = CLOCK_REALTIME; // is not a system call
//m_clockId = CLOCK_MONOTONIC_RAW; //is a system call
}
else{
//Process CPU time across all CPU core (threads)
m_clockId = CLOCK_PROCESS_CPUTIME_ID;
}
if (startImmediately){
start();
}
} void start(){
clock_gettime(m_clockId, &m_start);
m_end = m_start;
} void stop(){
clock_gettime(m_clockId, &m_end);
} //return - the passed time between start and last stop in nanoseconds
double getNseconds() const{
return (m_end.tv_sec - m_start.tv_sec) * SECOND_IN_NS + (m_end.tv_nsec - m_start.tv_nsec);
} //return - the passed time between start and last stop in seconds
double getSeconds() const{
return (m_end.tv_sec - m_start.tv_sec) + double(m_end.tv_nsec - m_start.tv_nsec) / SECOND_IN_NS;
} //return - the passed seconds without need of stopping the execution
double getSecondsAndContinue() const{
struct timespec tempEnd;
clock_gettime(m_clockId, &tempEnd);
return (tempEnd.tv_sec - m_start.tv_sec) + double(tempEnd.tv_nsec - m_start.tv_nsec) / SECOND_IN_NS;
} time_t getS() const{
time_t ret = m_end.tv_sec - m_start.tv_sec;
if (m_end.tv_nsec < m_start.tv_nsec){
ret -= ;
} return ret;
} time_t getNs() const{
if (m_end.tv_nsec >= m_start.tv_nsec){
return m_end.tv_nsec - m_start.tv_nsec;
}
return SECOND_IN_NS + m_end.tv_nsec - m_start.tv_nsec;
} friend std::ostream& operator <<(std::ostream& os, const Timer& timer);
}; std::ostream& operator <<(std::ostream& os, const Timer& timer){
char nsBuf[]; //999, 999, 999
if (timer.m_end.tv_nsec >= timer.m_start.tv_nsec){
os << timer.m_end.tv_nsec - timer.m_start.tv_sec;
snprintf(nsBuf, sizeof(nsBuf), "%09li", timer.m_end.tv_nsec - timer.m_start.tv_nsec);
}
else{
os << timer.m_end.tv_nsec - timer.m_start.tv_sec - ;
snprintf(nsBuf, sizeof(nsBuf), "%09li", SECOND_IN_NS + timer.m_end.tv_nsec - timer.m_start.tv_nsec);
}
return os<<"."<<nsBuf;
} void set(int& n){ //被for_each调用
static int value = ;
n = value++;
} void print(int n){ //被for_each调用
cout<<n<<endl;
} int main(){
/*test short copy*/
vector<int> iVec();
for_each(iVec.begin(), iVec.end(), set);
//for_each(iVec.begin(), iVec.end(), print); int* pInt = new int[iVec.size()]; Timer timer;
copy(iVec.begin(), iVec.end(), pInt);
timer.stop();
cout<<"the short copy cost("<<timer.getSeconds()<<")'s"<<endl; timer.start();
int size = iVec.size();
for (int i = ; i < iVec.size(); i++)
{
pInt[i] = iVec[size - i - ];
}
timer.stop();
cout<<"the short loop cost("<<timer.getSeconds()<<")'s"<<endl;
   delete []pInt;
cout<<"---------------------------------------"<<endl; /*test long copy*/
vector<int> iVec2();
for_each(iVec2.begin(), iVec2.end(), set);
//for_each(iVec.begin(), iVec.end(), print); int* pInt2 = new int[iVec2.size()]; Timer timer2;
copy(iVec2.begin(), iVec2.end(), pInt2);
timer2.stop();
cout<<"the long copy cost("<<timer2.getSeconds()<<")'s"<<endl; timer2.start();
int size2 = iVec2.size();
for (int i = ; i < iVec2.size(); i++)
{
pInt2[i] = iVec2[size2 - i - ];
}
timer2.stop();
cout<<"the long loop cost("<<timer2.getSeconds()<<")'s"<<endl;
delete []pInt2;
return ;
}
编译命令: g++ -o test main.cpp -lrt

测试结果,跟作者的大相径庭,不知是和原因:

std::copy的使用的更多相关文章

  1. std::copy性能分析与memmove机器级实现

    复制数据的快速方法std::copy C++复制数据各种方法大家都会,很多时候我们都会用到std::copy这个STL函数,这个效率确实很不错,比我们一个一个元素复制或者用迭代器复制都来的要快很多. ...

  2. 闲:测试memcpy和std::copy vector之间拷贝

    预测:底层C函数肯定比stl算法快 结果:少量数据底层快,大数据以上则stl对vector的处理可能更好 C/C++: #include <iostream> #include <v ...

  3. std::copy 和 std::back_inserter

    #define print_vector(v1) \ for(auto iter = v1.begin();iter != v1.end();iter++) \ cout<<*iter&l ...

  4. std::copy ( myvector.begin(), myvector.end(), out_it )

    在实际生产环境中,不能进行调试,所以程序通常需要编译一个DEBUG版本来辅助我们找出问题所在,编译这样的DEBUG版本最常用的手段就是在关键处输出我们关心一些变量的值到屏幕. 如果输出的简单的变量值, ...

  5. std::copy使用方法

    推荐2个c++函数库,类定义的资料库: http://en.cppreference.com/w/cpp/algorithm/copy http://www.cplusplus.com/referen ...

  6. C++11 std::copy

    这个函数并不是简单的 while(first != last) { *result = *first; result++; first++; } 事实上这种写法是最具普适性的,值要求inputIter ...

  7. How to copy the contents of std::vector to c-style static array,safely?

    [问题] I am getting warning when using the std copy function. I have a byte array that I declare. byte ...

  8. std::vector数据复制

    std::vector<boost::shared_ptr <ITEM> > srcItemList;  // 数据源 std::vector<ITEM>  des ...

  9. C++ STL copy函数效率分析

    在C++编程中,经常会配到数据的拷贝,如数组之间元素的拷贝,一般的人可能都会用for循环逐个元素进行拷贝,在数据量不大的情况下还可以,如果数据量比较大,那么效率会比较地下.而STL中就提供了一个专门用 ...

随机推荐

  1. 职责链模式vs状态模式区别

    状态模式在具体状态里设置了下一状态. 而职责链模式是在客户端代码里设置了下一状态的处理对象. 如果状态模式里的任何一环缺失,将导致事情无法进行下去.职责链模式的链式在客户端连接的,也就是说,如果我们请 ...

  2. (step6.3.4)hdu 1151(Air Raid——最小路径覆盖)

    题意:     一个镇里所有的路都是单向路且不会组成回路. 派一些伞兵去那个镇里,要到达所有的路口,有一些或者没有伞兵可以不去那些路口,只要其他人能完成这个任务.每个在一个路口着陆了的伞兵可以沿着街去 ...

  3. CRF++使用小结(转)

    1. 简述 近期要应用CRF模型,进行序列识别.选用了CRF++工具包,详细来说是在VS2008的C#环境下,使用CRF++的windows版本号.本文总结一下了解到的和CRF++工具包相关的信息. ...

  4. android95 缩放加载大图片

    MainActivity: package com.itheima.loadimage; import android.os.Bundle; import android.app.Activity; ...

  5. iOS 网络编程:XML解析

    1 XML文档结构 1.1 简介 XML 指可扩展标记语言(eXtensible Markup Language).XML 被设计用来传输和存储数据.其非常像HTML的标记语言,但与之不同的是,XML ...

  6. find which process occupy the PORT

    mac :   lsof -i:8080 linux : netstat -anltp | grep 8080

  7. mysql中查询某字段所在的表方法

    select TABLE_NAME from information_schema.COLUMNS where COLUMN_NAME = 'type'

  8. Java并发——线程池Executor框架

    线程池 无限制的创建线程 若采用"为每个任务分配一个线程"的方式会存在一些缺陷,尤其是当需要创建大量线程时: 线程生命周期的开销非常高 资源消耗 稳定性 引入线程池 任务是一组逻辑 ...

  9. MySQL约束

    MySQL中约束保存在information_schema数据库的table_constraints中,可以通过该表查询约束信息: 常用5种约束: not null: 非空约束,指定某列不为空 uni ...

  10. _In_ 是什么意思

    函数参数类型前 _In_代表什么     在visual C++中属于SAL批注,是为了编译系统在分析代码时发现缺陷用的   表示是一个输入参数.可以定义一个_In_的宏,这个宏什么都不做, 就是形如 ...