2017-07-13 78 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()那麼矢量需要分配新的存儲並將元素移動到新的存儲。如果它不能這樣做,那麼矢量不能按預期運行。