我正在尝试将两个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
答案 0 :(得分:6)
致电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);
并不大,如果你做得更多,你可能会过度工程化。
进一步扩展可让您在向量中设置char
或resize()
大小,以避免在第二次复制期间不可避免地调整大小。