C++ 使用默认构造函数在向量中放置
我想使用C++ 使用默认构造函数在向量中放置,c++,c++11,vector,emplace,C++,C++11,Vector,Emplace,我想使用vector::emplace默认构造一个不可复制的和不可分配的对象,然后使用迭代器对新创建的对象使用特定方法。请注意,该类没有参数化构造函数,只有默认构造函数。一个简单的例子是: #include <iostream> #include <vector> using namespace std; class Test { public: Test() {} private: Test(const Test&) = delete;
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;
}
向量有类似的东西吗?对于
map
,很简单:
std::map<int, Object> obj_map;
obj_map[10]; // default-constructs an object with key 10
[编辑]向量的等价物是emplace\u back:
obj_vector.emplace_back(); // default construct
obj_vector.emplace_back(args, to, std::move(construct), with); // forward these
vector::emplace_back()
将在向量末尾构造,但也需要参数
参数包可以为空。因此,变量模板emplace\u back
可以在没有参数的情况下调用;即
vector<VeryLimitedClass> vec;
vec.emplace_back();
vec;
向量放置回();
是通过默认构造函数初始化类型为
VeryLimitedClass
的对象并将其“放置”在vec
后面的有效代码,正如@dyp和@Casey在注释中指出的那样,std::emplace
将不适用于测试类的向量,因为该类也是不可移动的,因为“用户声明的复制构造函数禁止生成默认移动构造函数”(@Casey)
要在此处使用emplace
,该类需要可移动。我们可以通过显式定义(并默认)移动构造函数来实现这一点:
public:
Test(Test&& other) = default;
Test& operator=(Test&& other) = default;
这也会隐式地使类不可复制“因为声明移动操作将禁止隐式生成副本。”(@Casey)
现在我们可以使用
std::emplace_back()
,然后使用vector::back()
调用新创建对象的方法。很明显,可以使用std::pieclewise_construct
进行贴图。然而,我的问题是对向量做同样的处理。我想我也遗漏了一些信息(我现在已经编辑过):注意,类型不可复制或分配,因此将emplace与其他对象一起使用是不合适的。@RizwanC啊,我不理解你的问题。已为vector
更新。您的类型可移动吗?是的,但不可分配或复制。请看一个例子。使用emplace\u back()
会导致编译错误。@RizwanC该错误是因为类型不可移动。用户声明的复制构造函数禁止生成默认移动构造函数。您需要声明一个默认的移动构造函数(以及移动赋值,如果您愿意),此时您不需要删除的复制操作,因为声明移动操作将禁止隐式生成副本。该类型是不可移动的。移动函数不是隐式声明(或删除)的,因为您已显式声明了复制函数。我明白了,所以可以安全地假设我们无法将默认构造函数放置到具有此类型的向量中吗?@dyp。。。你完全明白我的意思。我不想把OP和标准术语混为一谈。:)有趣的是,无论是从向量还是从分配器需求,都无法保证发生了什么样的初始化。但是,是的,它可能不太在乎我没有对这个答案投赞成票,因为我不确定我们是否已经了解了整个情况。如果OP具有不可复制和不可更改的类型,则不能使用emplace
。@dyp您确定上次评论的第一部分吗?我知道我想报告一个缺陷,因为与此相关的IIRC(以及vector的异常安全保证)已超过一年。当时我已经彻底研究了这个问题。我们可以肯定地说,默认分配器将按照[allocator.members]/12执行值初始化,这表示构造(U*p,Args&…Args)
的效果相当于::new((void*)p)U(std::forward(Args)
。但是,即使知道向量的类型是std::vector
,我们也不能肯定地说默认分配器正在使用,因为std::allocator
可能是用户定义的专门化。
vector<VeryLimitedClass> vec;
vec.emplace_back();
public:
Test(Test&& other) = default;
Test& operator=(Test&& other) = default;