std::move
在单个矢量元素上的行为是什么?
例如(以下是非常简化的代码)
这会正确移动吗,我需要erase()
移动的元素吗?
我通常使用复制构造函数和删除函数,在某些情况下编译器会优化移动(合成)而不使用复制构造函数吗?
我尝试使用智能指针包装器,但没有看到明显的加速。 移动语义看起来像我想使用的。
template< class T >
class Foo
{
};
vector< Foo< T > > v1, v2;
v2.emplace_back( std::move( v1[ 2 ] );
使用移动操作没有看到明显的提速,并且我认为我已经正确实现了移动构造函数和移动赋值运算符。
请阐明此问题。
答案 0 :(得分:0)
移动语义有两个工作:
例如,假设我们有一个向量:
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";
}