2014-11-21 191 views
1

矢量安放我想用vector::emplace默認構造不可複製不可轉讓對象,然後使用迭代到新創建的對象使用對象的具體方法。請注意,沒有該類的參數化構造函數只是默認的構造函數。一個簡單的例子是:使用默認的構造函數

#include <iostream> 
#include <vector> 
using namespace std; 

class Test { 
public: 
    Test() {} 
private: 
    Test(const Test&) = delete;    // To make clas un-copyable. 
    Test& operator=(const Test&) = delete; 

    int a_; 
}; 

int main() { 
    vector<Test> test_vec; 
    test_vec.emplace_back();  // <---- fails 

    return 0; 
} 

vector::emplace()構造一個新的對象,但需要的參數,以一個非默認的構造函數。 vector::emplace_back()將在向量的末尾構造。

有沒有一種方法來安裝默認構造。有沒有一種方法可以使用分段結構或默認轉發,可能使用std::piecewise_construct,因爲它具有地圖功能?例如,在地圖的情況下,我們可以使用:

std::map<int,Test> obj_map; 
int val = 10; 
obj_map.emplace(std::piecewise_construct, 
       std::forward_as_tuple(val), 
       std::forward_as_tuple()); 

有什麼類似的向量?

+0

您的類型是否可移動? – dyp 2014-11-21 18:45:41

+0

是的,但它不可分配或可複製。請看一個例​​子[這裏](http://ideone.com/49LKaP)。使用'emplace_back()'會導致編譯錯誤。 – 2014-11-21 19:05:39

+0

@RizwanC該錯誤是因爲該類型不*可移動*。用戶聲明的複製構造函數禁止生成默認的移動構造函數。您需要聲明一個默認的移動構造函數(如果願意,還可以移動賦值),此時您不需要刪除的複製操作,因爲聲明移動操作會抑制隱式生成副本。 – Casey 2014-11-21 19:06:21

回答

2

正如在評論@dyp和@Casey指出,std::emplace不會爲測試類的矢量工作作爲類也不可移動因爲」用戶聲明的拷貝構造函數抑制的默認移動代構造函數「(@Casey)。

要在這裏使用emplace,課程將需要移動。我們可以通過顯式定義(和默認)移動構造做到這一點:

public: 
    Test(Test&& other) = default; 
    Test& operator=(Test&& other) = default; 

這也將隱含使課堂不-可複製「自從宣佈移動操作將抑制副本的隱代」 (@Casey)

現在我們可以使用std::emplace_back()然後用vector::back()來調用新建對象的方法。

0

對於map,容易:

std::map<int, Object> obj_map; 
obj_map[10]; // default-constructs an object with key 10 

否則,你有什麼作品也:

obj_map.emplace(std::piecewise_construct, 
       std::forward_as_tuple(10), 
       std::forward_as_tuple(args, to, construct, with)); 

[編輯]爲vector等效爲emplace_back

obj_vector.emplace_back(); // default construct 
obj_vector.emplace_back(args, to, std::move(construct), with); // forward these 
+1

很明顯,你可以對地圖使用'std :: piecewise_construct'。但是,我的問題是關於向量做同樣的事情。我想我也留下了一些信息(我現在編輯過):請注意,該類型不可複製或分配,因此使用emplace與其他對象不適合。 – 2014-11-21 18:42:40

+0

@RizwanC啊,我不明白你的問題。更新它爲'vector'。 – Barry 2014-11-21 18:49:18

5

vector::emplace_back()將在向量的末尾構造,但也需要參數。

參數包可以是空的。因此可以不帶參數地調用可變參數模板emplace_back;即

vector<VeryLimitedClass> vec; 
vec.emplace_back(); 

那是在vec後通過其默認的構造函數和「emplaces」它初始化VeryLimitedClass類型的對象的有效代碼。

+0

@dyp ...你確切地知道我的意思。我不想將OP與標準術語混淆。 :) – Columbo 2014-11-21 18:47:21

+0

有趣的是,無法保證向量和分配器的要求都不會發生什麼類型的初始化。但是,是的,它可能並不在乎。 - 我還沒有提出這個答案,因爲我不確定我們是否已經知道整個圖片。如果OP具有不可移動的AND不可移動類型,則不能使用「emplace」。 – dyp 2014-11-21 18:48:54

+1

@dyp你確定你最後的評論的第一部分? – Columbo 2014-11-21 18:50:17