可以std :: vector emplace_back从矢量本身的元素复制构造吗? [英] Can std::vector emplace_back copy construct from an element of the vector itself?

查看:437
本文介绍了可以std :: vector emplace_back从矢量本身的元素复制构造吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当使用 push_back of std :: vector 时,我可以推送向量本身的元素,由于重新分配而使参数无效:

  std :: vector< std :: string& v = {a,b}; 
v.push_back(v [0]); //这是确定即使v.capacity()== 2在此调用之前。但是,当使用 emplace_back 时,<$ std :: vector 将参数转发到 std :: string 的构造函数,以便在向量中发生复制构造。这使我怀疑向量的重新分配发生在新的字符串被复制之前(否则它不会被分配到位),因此在使用之前使自变量无效。



这意味着我不能用 emplace_back 添加向量本身的元素,或者在重新分配的情况下我们有一些保证,类似于 push_back



在代码中:

  std :: vector< std :: string> v = {a,b}; 
v.emplace_back(v [0]); //这是有效的,即使在这个调用之前v.capacity()== 2吗?


解决方案

emplace_back 因同一原因必须是安全的 push_back 需要安全;



在实践中,这意味着 emplace_back 需要按照以下顺序执行重新分配(忽略错误处理):


  1. 分配新容量

  2. 在新数据段末尾构建新元素

  3. 将现有元素移动到新数据段中

  4. 销毁和取消分配

  5. a_commonly_unknown_stdvector_pitfall />此补充线程 STL确认VC11的故障支持 v.emplace_back(v [0])作为一个错误,因此您应该肯定检查



    请注意,某些形式的自我插入标准明确禁止的例如 [sequence.reqmts] 段落4表100 a.insert(p,i,j)具有前提条件 i j 不是迭代器 a


    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.
    

    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.

    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?

    In code:

    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 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.

    In practice, this means that emplace_back performing a reallocation is required to proceed in the following order (ignoring error handling):

    1. Allocate new capacity
    2. Emplace-construct new element at the end of the new data segment
    3. Move-construct existing elements into new data segment
    4. Destruct and deallocate old data segment

    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.

    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从矢量本身的元素复制构造吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆