【发布时间】:2014-09-14 12:47:50
【问题描述】:
当使用push_back 或std::vector 时,我可以推送向量本身的元素,而不必担心由于重新分配而使参数无效:
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 的构造函数,以便在向量中进行复制构造。这让我怀疑向量的重新分配发生在新字符串被复制构造之前(否则它不会被分配到位),从而在使用前使参数无效。
这是否意味着我不能用emplace_back 添加向量本身的元素,或者我们是否有某种保证以防重新分配,类似于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?
【问题讨论】:
-
什么是“害怕由于重新分配而使论点无效”?
-
@xylosper 如果您处于向量容量的限制,push_back/emplace_back 将重新分配向量以增加其大小。如果发生重新分配,则对该向量的元素和迭代器的引用无效。在这种情况下, push_back 的参数在使用之前可能会失效。然而,事实证明 std::vector 跳过了箍,因此这对 push_back 来说不是问题。
-
我认为理论上是可以保证的,但在实践中你可能会遇到它作为一个错误,所以你应该尽量避免它。
-
@rasmus:我认为与
push_back案例完全相同的推理适用:没有什么限制这个论点,因此它很可能来自同一个向量 -
这个问题通过
emplace变得更有趣:cplusplus.github.io/LWG/lwg-active.html#2164