在单个向量元素上移动语义

问题描述 投票:-1回答:1

std::move在单个向量元素上的行为是什么?例如(紧随其后的代码)

这会做正确的举动吗?我需要erase()移动的元素吗?

我通常使用复制构造函数和删除,编译器是否会优化移动(合成)而不是在某些情况下使用复制构造函数?

我尝试使用智能指针包装器,并没有看到显着的加速。移动语义看起来像我想要使用的。

template< class T >
class Foo
{
};

vector< Foo< T > > v1, v2;

v2.emplace_back( std::move( v1[ 2 ] );

我没有看到使用移动操作的显着加速,我认为我已经实现了移动构造函数并正确地移动赋值运算符。

请详细说明这个问题。

c++ vector move-semantics
1个回答
0
投票

移动语义有两个作业:

  • 指示资源的所有权(例如某些已分配的内存,或FILE *指针或流)已转手
  • 在上述情况下避免不必要的副本。

例如,假设我们有一个向量:

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"; 
}
© www.soinside.com 2019 - 2024. All rights reserved.