How do you copy the contents of an array to a std::vector in C++ without looping? (From stack over flow)

I have an array of values that is passed to my function from a different part of the program that I need to store for later processing. Since I don‘t know how many times my function will be called before it is time to process the data, I need a dynamic storage structure, so I chose a std::vector. I don‘t want to have to do the standard loop to push_back all the values individually, it would be nice if I could just copy it all using something similar to memcpy.

There have been many answers here and just about all of them will get the job done.

However there is some misleading advice!

Here are the options:

vector<int> dataVec;

int dataArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
unsigned dataArraySize = sizeof(dataArray) / sizeof(int);

// Method 1: Copy the array to the vector using back_inserter.
{
    copy(&dataArray[0], &dataArray[dataArraySize], back_inserter(dataVec));
}

// Method 2: Same as 1 but pre-extend the vector by the size of the array using reserve
{
    dataVec.reserve(dataVec.size() + dataArraySize);
    copy(&dataArray[0], &dataArray[dataArraySize], back_inserter(dataVec));
}

// Method 3: Memcpy
{
    dataVec.resize(dataVec.size() + dataArraySize);
    memcpy(&dataVec[dataVec.size() - dataArraySize], &dataArray[0], dataArraySize * sizeof(int));
}

// Method 4: vector::insert
{
    dataVec.insert(dataVec.end(), &dataArray[0], &dataArray[dataArraySize]);
}

// Method 5: vector + vector
{
    vector<int> dataVec2(&dataArray[0], &dataArray[dataArraySize]);
    dataVec.insert(dataVec.end(), dataVec2.begin(), dataVec2.end());
}

Here are some gory details:

Method 1 is probably the easiest to understand. Just copy each element from the array and push it into the back of the vector. Alas, it‘s slow. Because there‘s a loop (implied with the copy function), each element must be treated individually; no performance improvements can be made based on the fact that we know the array and vectors are contiguous blocks.

Method 2 is a suggested performance improvement to Method 1; just pre-reserve the size of the array before adding it. For large arrays this might help. However the best advice here is never to use reserve unless profiling suggests you may be able to get an improvement (or you need to ensure your iterators are not going to be invalidated). Bjarne agrees. Incidentally, I found that this method performed the slowest most of the time though I‘m struggling to comprehensively explain why it was regularly significantly slower than method 1...

Method 3 is the old school solution - throw some C at the problem! Works fine and fast for POD types. In this case resize is required to be called since memcpy works outside the bounds of vector and there is no way to tell a vector that its size has changed. Apart from being an ugly solution (byte copying!) remember that this can only be used for POD types. I would never use this solution.

Method 4 is the best way to go. It‘s meaning is clear, it‘s (usually) the fastest and it works for any objects. There is no downside to using this method for this application.

Method 5 is a tweak on Method 4 - copy the array into a vector and then append it. Good option - generally fast-ish and clear.

Finally, you are aware that you can use vectors in place of arrays, right? Even when a function expects c-style arrays you can use vectors:

vector<char> v(50); // Ensure there‘s enough space
strcpy(&v[0], "prefer vectors to c arrays");
时间: 2024-10-05 11:14:53

How do you copy the contents of an array to a std::vector in C++ without looping? (From stack over flow)的相关文章

Looping through the contents of an array

In this lesson, you'll learn to use the foreach loop, which is designed to handle arrays and certain types of PHP objects. The foreach loop can be used in two different ways. The first gives you the access to the value of each array element. The synt

C#ConcurrentDictionary源代码

using System; using System.Collections.Generic;using System.Text; using System.Threading; using System.Runtime.InteropServices;using System.Diagnostics; using System.Collections;using System.Runtime.Serialization;using System.Security;using System.Se

CSDN回帖得分大全(近两年)

CSDN回帖得分大全(近两年) √ vs2005调用dll的时候Initialize()函数返回错误[VC/MFC 基础类] √ 为什么我创建登陆框之后,然后获取登陆框的数据时候总是出现非法操作![VC/MFC 界面] √ CFileFind::FindFile   支持通配符么?[VC/MFC 基础类] √ vc++   浮动窗口联动的实现[VC/MFC 界面] √ VC   从数据库中读出数据流后怎么判断文件格式[VC/MFC 数据库] √ windows   7接硬體,不會自動刷新   請

OpenMP初步(英文)

Beginning OpenMP OpenMP provides a straight-forward interface to write software that can use multiple cores of a computer. Using OpenMP you can write code that uses all of the cores in a multicore computer, and that will run faster as more cores beco

【共读Primer】64.[7.3]类类型 Page249

类类型 对于类来说每个类的定义都是唯一的类型,即使两个类的成员完全一样,他们仍然是不同的类型 struct First { int memi; int getMem(){return memi;}; }; struct Second { int memi; int getMem(){return memi;}; }; First obj1; Second obj2 = obj1; // 两个不同的类型无法进行赋值操作 类的声明 同函数一样,类也可以只声明而不定义,这种语法的常用场景是在使用类的地

STL 序列容器

转自时习之 STL中大家最耳熟能详的可能就是容器,容器大致可以分为两类,序列型容器(SequenceContainer)和关联型容器(AssociativeContainer)这里介绍STL中的各种序列型容器和相关的容器适配器.主要内容包括 std::vector std::array std::deque std::queue std::stack std::priority_queue std::list std::forward_list std::vector 1)初始化 int ini

c++11 vector使用emplace_back代替push_back

C++11中,针对顺序容器(如vector.deque.list),新标准引入了三个新成员:emplace_front.emplace和emplace_back,这些操作构造而不是拷贝元素.这些操作分别对应push_front.insert和push_back,允许我们将元素放置在容器头部.一个指定位置之前或容器尾部. 当调用push或insert成员函数时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中.而当我们调用一个emplace成员函数时,则是将参数传递给元素类型的构造函数.em

C++11 std::copy

这个函数并不是简单的 while(first != last) { *result = *first; result++; first++; } 事实上这种写法是最具普适性的,值要求inputIterator是输入迭代器,outputIterator是输出迭代器 可以想像我们熟悉的链表,vector之类的迭代器都是满足要求的.但这种最具普适性的写法性能却不咋地. 习惯C语言的应该都很喜欢memcpy这个函数,确实高效.在C++里,不是所有的对象拷贝都能简单的memcpy的, c++11给出了一个

实战c++中的vector系列--copy set to vector(别混淆了reserve和resize)

stl算法中有个copy函数.我们能够轻松的写出这种代码: #include <iostream> #include <algorithm> #include <vector> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { double darray[10]={1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9}; vector<double> vdoubl