简单的示例是返回的函数的参数。该标准明确禁止在这种情况下省略移动(不是他们可以......):
std::vector<int> multiply( std::vector<int> input, int value ) {
for (auto& i : input )
i *= value;
return input;
}
此外,您可以显式请求移动构造,以获得更简单但更人为的示例:
T a;
T b( std::move(a) );
嗯......还有一个不涉及std::move
(从技术上讲可以省略,但大多数编译器可能不会):
std::vector<int> create( bool large ) {
std::vector<int> v1 = f();
std::vector<int> v2 = v1; // modify both v1 and v2 somehow
v2.resize( v2.size()/2 );
if ( large ) {
return v1;
} else {
return v2;
}
}
而优化器可以通过将代码重写为:
std::vector<int> create( bool large ) {
if ( large ) {
std::vector<int> v1 = f();
std::vector<int> v2 = v1; // modify both v1 and v2 somehow
v2.resize( v2.size()/2 );
return v1;
} else {
std::vector<int> v1 = f();
std::vector<int> v2 = v1; // modify both v1 and v2 somehow
v2.resize( v2.size()/2 );
return v2;
}
}
我非常怀疑编译器是否会真正做到这一点。请注意,在每个代码路径中,返回的对象是已知的v1
并且v2
是在创建之前创建的,因此优化器可以在重写后在返回位置找到正确的对象。
可以省略复制/移动的情况在 12.8/31 中进行了描述。如果您设法编写不属于这些类别的代码并且该类型具有移动构造函数,则将调用移动构造函数。