STL向量:移动向量的所有元素

ami*_*far 47 c++ stl stdvector

我有两个STL向量A,B并且我想清除所有元素A并将所有元素移动BA然后清除B.简单地说,我想这样做:

std::vector<MyClass> A;
std::vector<MyClass> B;
....
A = B;
B.clear();
Run Code Online (Sandbox Code Playgroud)

因为B可能很长,所以需要k*O(N)执行此操作,其中k是常量,并且Nmax(size_of(A), size_of(B)).我想知道是否有更有效的方法可以做到这一点.我能想到的一件事是定义AB作为指针,然后在恒定时间内复制指针并清除B.

mfo*_*ini 75

使用C++ 11,它很简单:

A = std::move(B);
Run Code Online (Sandbox Code Playgroud)

现在A包含以前所持的元素B,而B现在是空的.这避免了复制:内部表示只是简单地移动BA,所以这是一个O(1)解决方案.

对于C++ 03,正如Prætorian所说,你可以交换向量.该std::swap函数有一个特化,它以std::vectors为参数.这有效地交换了内部表示,因此您最终避免创建它们所持有的元素的副本.此功能O(1)也很复杂.

  • 仅供参考,B是*非空*,它处于**有效但未指定的状态**.根据标准,移动后"B"的大小不保证为"0".这就是为什么`swap()`仍然有用而且move不能替代它:它保证只要`A`为空,`B`现在也是空的. (12认同)
  • B那时已经是空的,所以B.clear()是没有操作的。是的,您仍然可以使用向量,它只是一个空向量。 (2认同)
  • 在这种情况下,@void.pointer cppreference 的文档确实与您相矛盾。std::vector 的移动构造函数定义包括:“使用移动语义用other 的内容构造容器。Allocator 通过移动构造从属于other 的分配器中获得。移动后,other 保证为空()” https ://en.cppreference.com/w/cpp/container/vector/vector (2认同)
  • @steeldotme你错了。您已经链接了move构造函数文档。该答案使用的是“移动分配”。 (2认同)

Pra*_*ian 14

如果你有一个C++ 11编译器,你可以B进入A.

A = std::move(B);
Run Code Online (Sandbox Code Playgroud)

如果您正在使用较旧的编译器,那么只swap需要两个

A.swap(B);
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,唯一的O(N)操作将清除内容A.在第一种情况下,清除将在赋值本身期间完成,而在第二种情况下,它将在B超出范围时发生(因为内容被交换).


小智 6

std::move 工作正常。这是相同的示例代码

    vector<int> v1 = {1,2,3,10,20,30,100,200,300,999};
    vector<int> v2;

    cout << "Size of v1 before move = " << v1.size() << endl;
    cout << "Capacity of v1 before move = " << v1.capacity() << endl;

    v2 = std::move(v1);

    cout << "Size of v2 after move = " << v2.size() << endl;
    cout << "Capacity of v2 after move = " << v2.capacity() << endl;

    cout << "Size of v1 after move = " << v1.size() << endl;
    cout << "Capacity of v1 after move = " << v1.capacity() << endl;

-----------Output-------------------------
Size of v1 before move = 10
Capacity of v1 before move = 10
Size of v2 after move = 10
Capacity of v2 after move = 10
Size of v1 after move = 0
Capacity of v1 after move = 0
Run Code Online (Sandbox Code Playgroud)


Dav*_*eas 5

我有两个STL向量A和B,我想清除A的所有元素并将B的所有元素移动到A,然后清除B。

这可以通过组合来完成swap。第一次交换AB上半场。然后swapstd::vector<>withB或 call clear()。不同的是,clear()不会释放内存,而只会销毁对象:

std::vector<int> a, b; // initialize them somehow
swap(a,b);

// clear b without releasing the memory:
std::size_t capacity = b.capacity();
b.clear();
assert(b.capacity()==capacity);

// or release the memory
std::vector<int>().swap(b);
assert(b.capacity()==0);
Run Code Online (Sandbox Code Playgroud)