将仅将构造函数移动到向量的对象推回
push back an object which has only move constructor to a vector
这是一个比较笼统的问题。在这个 post Where does a std::vector allocate its memory? 中它说 vector
默认在堆中分配它的元素。在 C++11 中,有移动语义并且 vector
支持它。如果我有一个只有 move 构造函数的对象,并且我已经在堆栈中声明了这个对象,现在我想 push_back
这个对象变成 vector
,被推回的那个还在堆?
一个示例可能是将声明为 std::thread t1(someFunc)
的堆栈推回 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?
}
移动对象会将状态从一个对象转移到另一个对象;这两个对象是分开的,位于不同的位置,之后在相同的位置仍然是单独的对象。
所以问题的答案是肯定的:向量中的对象在堆上,无论用于初始化它的对象位于何处。
向量中存储的实例将始终是与您推入的对象不同的对象,即使它已移动。移动对象只会调用移动构造函数,而不是为向量中创建的相应对象调用复制构造函数。
所以是的,你可以将一个只能移动的类型推入一个向量,但是不行,它不会以某种方式神奇地将一块堆栈 space 转换成一块堆 space。它只是在 vector 中创建一个新对象,并将堆栈上对象的 contents 移入其中。内容如何移动(即移动到底是什么)由每个对象决定——这就是移动构造函数所做的。
执行此操作的语法可能如下所示:
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();
在 C++11 中调用移动构造函数实际上并没有移动任何东西。它只是一种管理对象生命周期和所有权的机制。
调用移动构造函数实际上意味着:"copy this object, and by the way you can cannibalize any data structure already allocated for this object because I will not use it anymore".
这是一个比较笼统的问题。在这个 post Where does a std::vector allocate its memory? 中它说 vector
默认在堆中分配它的元素。在 C++11 中,有移动语义并且 vector
支持它。如果我有一个只有 move 构造函数的对象,并且我已经在堆栈中声明了这个对象,现在我想 push_back
这个对象变成 vector
,被推回的那个还在堆?
一个示例可能是将声明为 std::thread t1(someFunc)
的堆栈推回 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?
}
移动对象会将状态从一个对象转移到另一个对象;这两个对象是分开的,位于不同的位置,之后在相同的位置仍然是单独的对象。
所以问题的答案是肯定的:向量中的对象在堆上,无论用于初始化它的对象位于何处。
向量中存储的实例将始终是与您推入的对象不同的对象,即使它已移动。移动对象只会调用移动构造函数,而不是为向量中创建的相应对象调用复制构造函数。
所以是的,你可以将一个只能移动的类型推入一个向量,但是不行,它不会以某种方式神奇地将一块堆栈 space 转换成一块堆 space。它只是在 vector 中创建一个新对象,并将堆栈上对象的 contents 移入其中。内容如何移动(即移动到底是什么)由每个对象决定——这就是移动构造函数所做的。
执行此操作的语法可能如下所示:
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();
在 C++11 中调用移动构造函数实际上并没有移动任何东西。它只是一种管理对象生命周期和所有权的机制。
调用移动构造函数实际上意味着:"copy this object, and by the way you can cannibalize any data structure already allocated for this object because I will not use it anymore".