使用默认的构造函数
矢量安放我想用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());
有什么类似的向量?
正如在评论@dyp和@Casey指出,std::emplace
不会为测试类的矢量工作作为类也不可移动因为”用户声明的拷贝构造函数抑制的默认移动代构造函数“(@Casey)。
要在这里使用emplace
,课程将需要移动。我们可以通过显式定义(和默认)移动构造做到这一点:
public:
Test(Test&& other) = default;
Test& operator=(Test&& other) = default;
这也将隐含使课堂不-可复制“自从宣布移动操作将抑制副本的隐代” (@Casey)
现在我们可以使用std::emplace_back()
然后用vector::back()
来调用新建对象的方法。
对于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
很明显,你可以对地图使用'std :: piecewise_construct'。但是,我的问题是关于向量做同样的事情。我想我也留下了一些信息(我现在编辑过):请注意,该类型不可复制或分配,因此使用emplace与其他对象不适合。 – 2014-11-21 18:42:40
@RizwanC啊,我不明白你的问题。更新它为'vector'。 – Barry 2014-11-21 18:49:18
vector::emplace_back()
将在向量的末尾构造,但也需要参数。
参数包可以是空的。因此可以不带参数地调用可变参数模板emplace_back
;即
vector<VeryLimitedClass> vec;
vec.emplace_back();
那是在vec
后通过其默认的构造函数和“emplaces”它初始化VeryLimitedClass
类型的对象的有效代码。
您的类型是否可移动? – dyp 2014-11-21 18:45:41
是的,但它不可分配或可复制。请看一个例子[这里](http://ideone.com/49LKaP)。使用'emplace_back()'会导致编译错误。 – 2014-11-21 19:05:39
@RizwanC该错误是因为该类型不*可移动*。用户声明的复制构造函数禁止生成默认的移动构造函数。您需要声明一个默认的移动构造函数(如果愿意,还可以移动赋值),此时您不需要删除的复制操作,因为声明移动操作会抑制隐式生成副本。 – Casey 2014-11-21 19:06:21