编辑:考虑以下两个例子:
std::string x;
{
std::string y = "extremely long text ...";
...
x = y; // *** (1)
}
do_something_with(x);
struct Y
{
Y();
Y(const Y&);
Y(Y&&);
... // many "heavy" members
};
struct X
{
X(Y y) : y_(std::move(y)) { }
Y y_;
}
X foo()
{
Y y;
...
return y; // *** (2)
}
在这两个示例中,第1行和第2行的
y
即将被销毁。显然,它可以在两种情况下被视为rvalue并进行移动。在(1)中,其内容可以移动到x
中,在(2)中可以移动到X().y_
的临时实例中。我的问题是:
1)它是否会在上述任何一个示例中被移动? a) 如果是,根据什么标准规定? b) 如果不是,为什么?这是标准中的遗漏还是我没有考虑到的其他原因?
2)如果上面的答案是否定的。在第一个示例中,我可以将(1)更改为
x = std::move(y)
以强制编译器执行移动。在第二个示例中,我该怎么做才能告诉编译器y
可以移动?return std::move(y)
?注:我故意返回
Y
的实例而不是X
,以避免(N)RVO。
std::string
。但如果它是一个重量级对象或者持有数兆字节数据的非 COW 字符串呢? - Super-intelligent Shadestd::string
实现使用了一种写时复制跟踪机制,以使得复制更加便宜。在这里进行一些测试后,我发现性能下降了,尽管只有超过 16KB 的字符串才能测量出来。 - tadman