std::move
在单个向量元素上的行为是什么?例如(紧随其后的代码)
这会做正确的举动吗?我需要erase()
移动的元素吗?
我通常使用复制构造函数和删除,编译器是否会优化移动(合成)而不是在某些情况下使用复制构造函数?
我尝试使用智能指针包装器,并没有看到显着的加速。移动语义看起来像我想要使用的。
template< class T >
class Foo
{
};
vector< Foo< T > > v1, v2;
v2.emplace_back( std::move( v1[ 2 ] );
我没有看到使用移动操作的显着加速,我认为我已经实现了移动构造函数并正确地移动赋值运算符。
请详细说明这个问题。
移动语义有两个作业:
例如,假设我们有一个向量:
vector<int> a;
for(int i = 0; i < 10000; i++) {
a.push_back(i);
}
如果我写:
vector<int> b = a;
这会复制a
中的每个元素,因此这是一个缓慢的操作。但是,如果我写的话
vector<int> b = std::move(a);
a
中没有任何元素被复制,最终会更快。然而,a
不再拥有这些元素。我们可以使用以下代码演示它:
#include <vector>
#include <iostream>
int main() {
using std::vector;
vector<int> a = {1, 2, 3};
vector<int> b = std::move(a);
if(a.data() == nullptr) // This should be true now
std::cout << "a.data() is null now\n";
if(a.size() == 0)
std::cout << "a.size() is zero now\n";
}
在我的系统上,使用gcc和clang,打印此代码
a.data() is null now
a.size() is zero now
即使您有一个包装类,这也适用:
#include <vector>
#include <iostream>
template<class T>
class Wrapper {
public:
// Because all the members of Wrapper are public,
// the compiler automatically generates move and copy constructors
T value;
};
int main() {
using std::vector;
Wrapper<vector<int>> a = {{1, 2, 3}};
Wrapper<vector<int>> b = std::move(a);
// Same output as before
if(a.value.data() == nullptr)
std::cout << "a.data() is null now\n";
if(a.value.size() == 0)
std::cout << "a.size() is zero now\n";
}