2014-11-21 200 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