考虑en.cppreference.com关于std::vector::emplace_back
"将新元素追加到容器的末尾。元素是 就地构建,即不执行复制或移动操作。 调用元素的构造函数完全相同 提供给函数的参数。"
以下示例:
#include <vector>
struct A
{
A(int){}
A(A const&) = delete;
};
int main()
{
std::vector<A> vec;
vec.emplace_back(1);
return 0;
}
在线vec.emplace_back(1);
Visual Studio 2013 / GCC报告:
错误C2280:&#39; A :: A(const A&amp;)&#39; :尝试引用已删除的函数
错误:使用已删除的函数'A :: A(const A&amp;)'
错误是否正确?你能解释一下为什么吗?
答案 0 :(得分:12)
C ++ 11 23.2.1表101说明:
表达式:
a.emplace_back(args)
返回类型:
void
操作语义:追加由
T
构造的std::forward<Args>(args)...
类型的对象。 要求:T
从EmplaceConstructible
X
args
vector
。对于T
,MoveInsertable
也应为X
A
。
您的MoveInsertable
不符合std::vector
要求,因为您没有移动构造函数,并且只有一个已删除的复制构造函数。使用{{1}}以外的容器,it works。
答案 1 :(得分:7)
与增加向量大小的其他函数一样,emplace_back
有条件地重新分配向量(如果当前容量不够大)。如果它这样做,那么它需要将旧数组中的现有元素转换为新数组。
您的类没有移动构造函数(某些类具有编译器生成的移动,但不是因为您删除了复制构造函数)。因此,重新分配代码需要能够复制类型,而不能。
当然,对于这个调用,没有要复制的旧元素,但是emplace_back
函数无法实例化。