【发布时间】:2015-07-21 13:26:57
【问题描述】:
由于某种原因,我的临时本地对象在添加到向量时总是被复制构造/销毁,由于嵌套的std::reference_wrapper 导致问题,由于之后的复制构造和销毁(std::reference_wrapper 目标而变得无效)位于被破坏的对象内 -> 如果源对象被破坏,它们在复制构造的对象中无效)。但如果可能的话,我想完全避免额外的复制/销毁——这似乎是不可能的,因为无论我尝试什么,它总是想调用复制构造函数(即使使用std::vector::emplace_back)。
考虑到这个简单的例子(为了在不涉及std::reference_wrapper 的情况下更容易理解),它总是尝试调用复制构造函数 - 我不明白为什么。
#include <vector>
class A{
public:
A(int a) : a(a){ }
int getInt() const{ return a; }
A(const A&) = delete; /* to deny copy-construction */
private:
int a;
};
int main(int argc, char* argv[]){
std::vector<A> vec;
vec.emplace_back(3); /* tries to call copy constructor */
vec.push_back(A(3)); /* tries to call copy constructor */
vec.push_back(std::move(A(3))); /* tries to call copy constructor */
return 0;
}
任何想法我在这里缺少什么?
【问题讨论】:
-
a) 前两次尝试:为什么不应该这样做? b)关于 std::move 部分,您缺少移动构造函数(即 r 值引用参数)。
-
你用的是什么编译器?如果移动构造函数不是自动生成的,那么你永远不能希望调用移动构造函数。另外,对于 c++11,如果你想禁用复制,你应该考虑使用
A(const A&) = delete。 -
我正在使用 MS Visual Studio 2013。感谢
A(const A&) = delete的建议。 -
读取this
emplace_backreference,存储的类型必须是move insertable,这表明可以像::new((void*)p) T(rv)一样使用placement new,这将调用移动构造函数或如果没有移动构造函数,则为复制构造函数。 -
听起来你的类包含自引用。对于这种情况,您必须编写自己的复制/移动构造函数以获得正确的语义。大多数
vector操作要求对象至少是可移动的。仅仅完全禁用复制/移动对您没有多大帮助。
标签: c++ c++11 vector copy-constructor move-semantics