如何使用std :: move()将char []移动到vector <char>

时间:2017-08-10 14:09:46

标签: c++ c++11

我正在尝试将两个char数组char a[9000]; char b[9000]连接到容器std::vector<char>。由于阵列大小不小。我正在尝试使用std::move()

class obj
{
public:
obj &operator <<(char *&&ptr)
        {
            //???
            ptr = nullptr;
            return *this;
        }
private:
    std::vector<char> m_obj;
};

所以在主要功能

int main()
{
    obj o;
    enum {SIZE=9000};
    char a[SIZE]; memset(a, 1, SIZE);
    char b[SIZE]; memset(b, 2, SIZE);
    o << a << b;
    return 0;
}

我的问题是移动char *的正确方法是什么?

环境
Ubuntu 16.04.4 LTS
g ++ 5.4.0

4 个答案:

答案 0 :(得分:6)

TL;博士

致电reserve()并复制。

搬家有什么问题?

有几件事。首先,您似乎对std::move的期望是错误的。 std::move不会神奇地移动任何东西(或移动任何东西,包括非神奇的东西)。它的作用是对rvalue引用的强制转换,它可能启用在某些条件下移动。

第二,从C ++ 03开始,std::vector 保证将其元素连续布局在内存中(在C ++ 03之前无论如何都是这样的情况,但是没有给出了明确的保证)。如果您使用std::move,那么您必须使用晚于C ++ 03的版本,因此std::vector必须连续布局其元素。
这意味着除了完全重合的情况,两个数组恰好彼此相邻,没有办法将两个数组中的元素转换为矢量而不进行复制。它根本无法移动它们,因为至少必须重新定位(=复制)一个数组。

此外,我无法想象如何从一个阵列中移动元素就像你想要的那样。移动假定您接管所有权,这通常意味着您以某种方式修改移动的对象,使其仍然有效,但没有它以前拥有的任何资源。
如何使用在周围范围内具有自动存储持续时间的阵列?什么是在移动之后取消引用数组(这是可能的和合法的)呢?

此外,你想要将一个数组衰减到一个指针(这是完全合法的)然后以某种方式神奇地移动。但是,这不会移动数组的内容!您可以做的最好的事情是移动指针,但这没有意义,因为移动指针与复制它是一样的。

你无法复制数组元素,但你可以通过提前正确调用reserve()来保存一个内存分配和一个不必要的副本。

答案 1 :(得分:1)

好吧,char *并不是你想要移动的对象。因此,获得指针的右值引用并不完全有用。 为什么不尝试使用类似数组的移动方式并使用std :: move来自“算法”?

http://en.cppreference.com/w/cpp/algorithm/move

它看起来像那样:

obj& obj::addChars(char *ptr, size_t size = 9000u) {    
    m_obj.resize(size);
    std::move(ptr, ptr + size, m_obj.begin());
    return *this;
}

答案 2 :(得分:1)

以下是有效的,因为向量是连续的内存。 有必要调整向量的大小以保存要复制的元素的数量。

&amp; vc [0]是向量的第0个元素的存储器地址。 &amp; vc [SIZE]是向量的第9000个元素的内存地址,这是数组b应该从哪里开始。

这比执行迭代数组和push_back或分配向量元素要快得多。

enum {SIZE=9000};
char a[SIZE];
memset(a, 1, SIZE);

char b[SIZE];
memset(b, 2, SIZE);

// make a vector of characters
std::vector<char> vc;
// resize to hold two arrays
vc.resize(SIZE * 2);

// copy array a to the beginning of the vector
memcpy(&vc[0], a, SIZE);
// copy array b to the end of the vector
memcpy(&vc[SIZE], b, SIZE);

编辑:

std::vector<char> vc(SIZE * 2);

与create相同,然后调整大小。它将创建具有指定大小的向量,然后不需要调整大小。

答案 3 :(得分:0)

即使您使用Bool分配了数组,也无法获得向量来采用数组。副本将会发生。

建议的方法是new,在大多数实现中,它将被识别为std::copy可优化。

std::memcpy()

如果没有这么优化(不太可能),请使用#include <cstring> #include <iostream> #include <vector> #include <algorithm> #define SIZE 90 int main(void) { std::vector<char> v; v.resize(2*SIZE); char a[SIZE]; char b[SIZE]; std::memset(a, 'a', SIZE); std::memset(b, 'b', SIZE); std::copy(a,a+SIZE,v.begin()); std::copy(b,b+SIZE,v.begin()+SIZE); for(char c : v){ std::cout << c; } std::cout << std::endl; return 0; }

你如何在课堂上实现这个是另一个辩论。 您可以实现std::memcpy()成员。

正如其他人指出的那样,9000 add(char *start,char *end);并不大,如果你做得更多,你可能会过度工程化。

进一步扩展可让您在向量中设置charresize()大小,以避免在第二次复制期间不可避免地调整大小。