构造字符串向量时是否有任何副本?
Is there any copy when constructing a vector of strings?
以下代码在vector<string>
中拆分"我的字符串":
std::stringstream ss{"my string"};
std::vector<std::string> vec;
std::string tmp;
while (std::getline(ss, tmp, ' ')) {
vec.push_back(tmp);
}
我的理解是,getline
将其结果写入tmp
然后tmp
通过复制它被推送到向量中。但是,这样做会更有效vec.push_back(std::move(tmp))
这样我们避免复制吗?
我的理解是getline将其结果写入tmp,然后tmp通过复制它被推送到向量中。
这是正确的。 由于tmp
是一个左值,因此必须制作副本。
会更有效
vec.push_back(std::move(tmp))
这样我们就可以避免复制吗?
是的。 如果你使用move
,而不是复制整个字符串,你只有几个指针/整数交换。 这意味着它可以更快。 在每次迭代中使用getline
填充移动自字符串是安全的,因此无需担心(源(。
它不快的唯一方法是字符串具有短字符串优化,并且您放入字符串中的数据是否足够短以符合它的条件。 然后你正在处理一个实际的字符数组,你必须做一个复制,因为数组不能移动。
它更省时,只是稍微提高了内存效率。
无论哪种方式,您都在分配一定数量的字符串。移动临时字符串只会导致循环的最终迭代少分配一次。 但是,移动可以防止在每次迭代时在位置之间复制内存内容的 CPU 和 RAM I/O 开销。
相关文章:
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 如何在不产生任何垃圾的情况下获得C中的像素
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- 用callgrind追踪不必要的副本
- C++映射有2个键,这样任何1个键都可以用来获取值
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- RtlCaptureStackBackTrace未捕获任何帧
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 链表c++插入,所有情况都已检查,但没有任何工作
- 在为LINUX创建共享库时,如何避免STL的私有/弱副本
- C++模板函数,用于比较任何无符号整数和有符号整数
- 检查注册表项是否链接到(或副本)另一个注册表项
- Arduino millis() - millis() 怎么能等于 0 以外的任何东西?
- 尝试摆脱任何堆内存分配
- std::任何只用于移动的模板,其中副本ctor内的static_assert等于编译错误,但为什么
- 构造字符串向量时是否有任何副本?
- C 标准:通过复制返回以初始化无RVO的参考:是否有任何副本
- 指针是否可能在没有任何数据副本的情况下被向量所拥有
- 任何编译器真的会删除这些副本吗