2017-07-13 24 views
-3

我有一个对象,我想要精确构造一次,因为它所在的类通过向它们添加原始指针来跟踪它的对象。构建它内嵌看来虽然失败:Emplace回到失败的地方建设

// Defined utilities: 
ModuleClusterPlot(Type typeArg, const int& layer, const int& module, const int& ladder, const int& startEventArg, const int& endEventArg); 
~ModuleClusterPlot(); 
// Invalid utilities 
ModuleClusterPlot(ModuleClusterPlot& t_other) = delete; 
ModuleClusterPlot(ModuleClusterPlot&& t_other) = delete; 
ModuleClusterPlot& operator=(const ModuleClusterPlot& t_other) = delete; 
ModuleClusterPlot& operator=(ModuleClusterPlot&& t_other) = delete; 

调用通过布设构造回失败,因为它试图调用移动构造函数(为什么?):

moduleClusterPlots.emplace_back(t_type, t_layer, t_module, t_ladder, i, i); 

什么我错在这里做什么?我正在使用gcc 7.1.0std=c++14标志。

小例子:

#include <vector> 

class ModuleClusterPlot 
{ 
    public: 
     enum Type 
     { 
      foo = 0, 
      bar 
     }; 

     ModuleClusterPlot(Type typeArg); 
     ~ModuleClusterPlot(); 
     // Invalid utilities 
     ModuleClusterPlot(ModuleClusterPlot& t_other) = delete; 
     ModuleClusterPlot(ModuleClusterPlot&& t_other) = delete; 
     ModuleClusterPlot& operator=(const ModuleClusterPlot& t_other) = delete; 
     ModuleClusterPlot& operator=(ModuleClusterPlot&& t_other) = delete; 

}; 

int main() 
{ 
    std::vector<ModuleClusterPlot> collection; 
    collection.emplace_back(ModuleClusterPlot::foo); 
} 

我怎样才能防止在这里调用移动构造函数?

+5

你可以让这个[mcve]? – NathanOliver

+0

你写你想要添加'原始指针',但如果你得到一个错误消息,需要一个复制/移动构造函数,我想你试图插入一个对象而不是指针! –

+0

@ThomasSparber我将'this'添加到持有指针的静态对象。 –

回答

1

std::vector<T>::emplace_back需要移动构造函数或复制构造函数。原因是它可能需要重新分配内存并将现有对象移动/复制到新缓冲区中。

即使您只是在空向量上调用它,而实际上并不需要移动任何现有对象,请记住可以在空向量和非空向量上使用相同的函数emplace_back。该函数不可能知道它仅从空状态使用,所以当成员函数被实例化时,处理非空向量的代码也必须是有效的。

+0

我会将我的容器更改为链接列表,然后感谢您真正解释为什么它需要移动构建! –

0

您违反了emaplce_back的约束。如果我们看一下表101 [sequence.reqmts]我们有

需要:T应EmplaceConstructible成X从ARGS。 为载体,T也应MoveInsertable到X.

重点煤矿

由于类不动插入它不会与emplace_back工作。

这是必需的原因是因为size()变得大于capacity()那么矢量需要分配新的存储并将元素移动到新的存储。如果它不能这样做,那么矢量不能按预期运行。