当使用 std::vector
的 push_back
时,我可以推送向量本身的一个元素,而不必担心由于重新分配而使参数无效:
When using push_back
of std::vector
, I can push an element of the vector itself without fear of invalidating the argument due to reallocation:
std::vector<std::string> v = { "a", "b" };
v.push_back(v[0]); // This is ok even if v.capacity() == 2 before this call.
然而,当使用 emplace_back
时,std::vector
将参数转发给 std::string
的构造函数,从而发生复制构造在向量中的位置.这让我怀疑向量的重新分配发生在复制构造新字符串之前(否则它不会就地分配),从而在使用前使参数无效.
However, when using emplace_back
, std::vector
forwards the argument to the constructor of std::string
so that copy construction happens in place in the vector. This makes me suspect that reallocation of the vector happens before the new string is copy constructed (otherwise it would not be allocated in place), thus invalidating the argument before use.
这是否意味着我不能使用 emplace_back
添加向量本身的元素,或者我们是否有某种保证以防止重新分配,类似于 push_back
?
Does this mean that I cannot add an element of the vector itself with emplace_back
, or do we have some kind of guarantee in case of reallocation, similar to push_back
?
在代码中:
std::vector<std::string> v = { "a", "b" };
v.emplace_back(v[0]); // Is this valid, even if v.capacity() == 2 before this call?
emplace_back
出于同样的原因需要安全 push_back
是安全的;指针和引用的失效仅在修改方法调用返回后生效.
emplace_back
is required to be safe for the same reason push_back
is required to be safe; invalidation of pointers and references only has effect once the modifying method call returns.
实际上,这意味着 emplace_back
执行重新分配需要按以下顺序进行(忽略错误处理):
In practice, this means that emplace_back
performing a reallocation is required to proceed in the following order (ignoring error handling):
在 这个 reddit 线程 STL 承认 VC11 失败support v.emplace_back(v[0])
as a bug,所以你一定要检查你的库是否支持这种用法,而不是想当然.
At this reddit thread STL acknowledges failure of VC11 to support v.emplace_back(v[0])
as a bug, so you should definitely check whether your library supports this usage and not take it for granted.
请注意,标准明确禁止某些形式的自插入;例如在 [sequence.reqmts] 段 4 表 100 a.insert(p,i,j)
有先决条件i
和 j
不是 a
" 的迭代器.
Note that some forms of self-insertion are specifically prohibited by the Standard; for example in [sequence.reqmts] paragraph 4 Table 100 a.insert(p,i,j)
has the prerequisite "i
and j
are not iterators into a
".
这篇关于std::vector emplace_back 可以从向量本身的元素复制构造吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!