如何使用 std::move() 将 char[] 移动到向量<char>
How to use std::move() to move char[] to a vector<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;
}
我的问题是移动字符*的正确方法是什么?
环境:
优麒麟 16.04.4 LTS
g++ 5.4.0
tl;博士
拨打reserve()
并复制。
搬家怎么了?
几件事。首先,你似乎对std::move
的期望是错误的。std::move
不会神奇地移动任何东西(或者根本不移动任何东西,包括非魔法(。它的作用是强制转换为右值引用,这在某些情况下可能允许移动。
其次,从 C++03 开始,std::vector
保证其元素连续地排列在内存中(在 C++03 之前,无论如何都是事实,但没有给出明确的保证(。如果您使用std::move
那么您必须使用晚于 C++03 的版本,因此std::vector
必须连续布置其元素.
这意味着除了两个数组恰好彼此相邻的完全巧合的情况之外,没有办法在不复制的情况下将两个数组中的元素放入向量中。根本无法移动它们,因为必须至少重新定位一个数组(= 复制(。
此外,我无法想象如何以您打算的方式从数组中移动元素。移动假定您接管了所有权,这通常意味着您以某种方式修改了 moved-from 对象,使其仍然有效,但之前没有任何资源。
如何处理在周围范围内具有自动存储持续时间的数组?那么在移动后取消引用数组(这是可能的和合法的(将做什么?
此外,你想把一个数组衰减到一个指针上(这是完全合法的(,然后以某种方式神奇地移动。但是,这不会移动数组的内容!你能做的最好的事情就是移动指针,但这没有意义,因为移动指针与复制指针是一样的。
您无法绕过必须复制数组元素,但您可以通过提前正确调用reserve()
来节省一个内存分配和一个不必要的副本。
好吧,char* 并不是你想要移动的对象。因此,获取对指针的右值引用并不完全有帮助。 你为什么不尝试类似数组的移动方式并使用std::move from "algorithm"?
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;
}
以下工作是因为向量是连续内存。 有必要调整矢量的大小以容纳要复制的元素的数量。
&vc[0] 是向量第 0 个元素的内存地址。 &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);
与创建相同,然后调整大小。 它将创建具有指定大小的矢量,然后不需要调整大小。
即使您使用new
分配了数组,也无法获得 vector 来采用数组。将进行复制。
推荐的方法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()
.
如何在课堂上实现这一点是另一个争论。 您可以实现add(char *start,char *end);
成员。
正如其他人指出的那样,9000char
并不大,如果你做得更多,你可能会过度设计。
进一步的扩展将允许您在矢量中resize()
或reserve()
大小,以避免在第二次复制期间不可避免的调整大小。
- 在<uint8_t> <char> c++ 中将常量向量转换为常量向量
- 封送处理 - 转换 std::向量<char>到字符串^ 反之亦然
- 如何使用 std::move() 将 char[] 移动到向量<char>
- 将 C++ 字符串存储到 char* 向量中
- 为什么此代码无法将字符push_back到向量中<char>?
- 如何从向量转换为<char>数字整数
- 通过其char键对对象指针的C 向量进行排序
- 优化将标准::uint32_t插入到标准::向量<char>中
- 应对 std::字符串中的 std::<char>指针转换后的向量
- 静态常量 std::<char>没有堆的向量初始化?
- 我如何将 c++ 中的向量序列化为 char,以便于将 mondodb 用于后端
- C++:如何将 char 变量分配给向量<char>并访问该向量的元素进行比较?
- <char> 使用 int 值初始化向量
- 瓦尔格林德:在字符[]到标准::向量迁移之后"Invalid write of size 1"<char>
- 从 JNI 到 Java 的 char 向量
- 如何将char复制到char*向量中
- 从Cocos2dx的指针char向量写入sqlite文件
- 将<char>向量前 N 个元素转换为整数
- 将无符号int+字符串强制转换为无符号char向量
- 声明我的char向量数组时发生编译错误