在哪里使用std ::移动弦
Where to use std::move for strings?
我正在阅读这篇文章。
,我达到了以下代码。
我想知道:
-
std::move
对字符串有用(假设字符串足够长)? -
它是否使上一个字符串无效?
-
我应该在哪里使用它,我不应该在哪里?
。
class Name
{
public:
Name(std::string firstName, std::string lastName)
: firstName_(std::move(firstName))
, lastName_(std::move(lastName)) {}
void print() const
{
std::cout << lastName_ << ", " << firstName_ << 'n';
}
private:
std::string firstName_;
std::string lastName_;
};
我的技术总是在使用
constructor(const std::string& argument): field(argument)
当可移动类型的值消耗时,按值接受参数的习语是有意义的。使用消耗一个值,我的意思是将值转发到需要自己的值副本的东西。这里的原因是:
- 当通过值传递参数时,可以省略副本,例如,当参数是不同函数调用的结果时。即使无法阐明副本,也可能使该论点看起来像暂时的(例如,使用
std::move(arg)
)。 - 由于一个值传递到函数中,即该函数已经拥有一个副本,因此可以在需要的任何地方转发此值。
- 在最坏的情况下,该参数被复制了,但是由于需要一个值,因此也需要从
T const&
参数创建副本,并且假定额外的移动操作相对便宜。
因此,期望在最坏的情况下可能还有一些其他工作,但是在正常情况下,工作要少得多,因为只完成了一个移动操作而不是副本。
对于std::string
,由于其常见的短字符串优化,该参数比其他可移动类型要困难得多:而不是一些指针操作,可能需要传输字节。但是,在实践中,复制短字符串或指针实际上只是一个memcpy()
,然后可能是操作,表明移动操作的源不再包含需要发布的字符串。
因此,简单的规则是
消耗可移动对象时,按值接受参数并移动对象,而不是通过
T const&
传递参数并创建副本以消耗结果。
移动字符串时会消耗旧值:
std::string sa = "Was the string";
std::string sb = std::move(sa);
std::cout << "Old [" << sa << "] new [" << sb << "]" << std::endl;
输出:旧[]新[是字符串]
我假设,旧值无需复制即可进入新字符串。当您需要在某个结构中分配字符串字段以将其作为参数传递时,这应该是有效的,例如ROS:
中的参数。 std::string my_message = method_that_returns_just_a_string();
std_msgs::String message;
message.data = std::move(my_message);
my_message现在将包含一些"有效的未指定值"。示例输出包含空字符串,但您不应依靠此字符串。
也许是XML的1MB的不必要克隆。
相关文章:
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- 如何在窗口之间移动 std::unique_ptr 而不会冒内存泄漏的风险?
- 为什么移动 std::可选不重置状态
- C++:我可以重用/移动 std::list 元素从中间到结尾吗?
- 我应该移动 std::exchange ed 成员吗?
- 移动 std::bitset<N> 是否超过 N 个位置未定义的行为?
- 标准是否保证在移动std::p ackaged_task后安全使用std::future?
- 用于移动 std::shared_ptr 的函数声明
- 如何移动 std::ostringstream 的底层字符串对象?
- 移动std::shared_ptr会使程序崩溃
- c++11移动std::deque或std::list的插入
- 如何移动std::ostream
- 移动std::bind和std::thread中的语义/行为
- 为什么我不能移动 std::ofstream?
- 从char*中移动std::string的构造函数
- 移动 std::vector 成员的语义
- 移动std::unique_locks的std::矢量
- 复制/移动std::映射中键/值类型的要求
- 移动std::互斥锁的构造函数
- 在容器之间移动std::unique_ptr