将只有移动构造函数的对象推回到向量

All*_*nzi 2 c++ move vector c++11

这是一个相当普遍的问题.在这篇文章中,std :: vector在哪里分配内存?它表示vector默认情况下在堆中分配它的元素.在C++ 11中,有移动语义并vector支持这一点.如果我有一个只有移动构造函数的对象,并且我已经在堆栈中声明了这个对象,现在我想把push_back这个对象变成一个vector,那么那个被推回堆中的那个对象怎么办?

一个例子可能是将声明的堆栈推回到std::thread t1(someFunc)a中vector,如下所示

int main(){
      std::thread t1(someFunc);
      std::vector<std::thread> threads;
      threads.push_back(t1); // is the one being pushed back in the heap
                             // or in the stack? Is the answer generally
                             // true for objects which have only move
                             // constructors?
}
Run Code Online (Sandbox Code Playgroud)

Cam*_*ron 7

存储在向量中的实例将始终与您推入的对象不同,即使它已移动.移动对象仅调用移动构造函数而不是向量中创建的相应对象的复制构造函数.

所以,是的,你可以将一个可移动的类型推送到一个向量中,但不是,它不会以某种方式神奇地将一堆堆栈空间转换为一堆堆空间.它只是在向量中创建一个新对象,并将堆栈中对象的内容移入其中.内容如何移动(即移动是什么,确切地说)取决于每个对象来决定 - 这就是移动构造函数的作用.

执行此操作的语法可能如下所示:

std::vector<std::thread> threads;
std::thread t([]() { /* do something */ });

// You need `std::move` here to force the object to be treated as
// an r-value and get moved instead of trying to be copied.
threads.push_back(std::move(t));

// At this point `t` still exists (until the end of scope), but
// its contents (while valid) are indeterminate. It does not refer
// to the running thread any more.

threads.back().join();
Run Code Online (Sandbox Code Playgroud)