当前位置:  开发笔记 > 编程语言 > 正文

VS2013下的emplace_back()问题

如何解决《VS2013下的emplace_back()问题》经验,为你挑选了1个好方法。

请考虑以下代码

std::vector nums{21, 22, 23, 24};
nums.emplace_back(nums[0]);
nums.emplace_back(nums[1]);

for (auto n : nums) {
    std::cout << n << std::endl;
}

输出 VS2013

21
22
23
24
-17891602
22

为什么会在-17891602这里?

输出GCC 4.8.4正确如下

21
22
23
24
21
22

然后我比较的执行emplace_back之间VS2013GCC

VS2013

template
    void emplace_back(_Valty&&... _Val)
    {   // insert by moving into element at end
    if (this->_Mylast == this->_Myend)
        _Reserve(1);
    _Orphan_range(this->_Mylast, this->_Mylast);
    this->_Getal().construct(this->_Mylast,
        _STD forward<_Valty>(_Val)...);
    ++this->_Mylast;
    }

GCC

template
template
  void
  vector<_Tp, _Alloc>::
  emplace_back(_Args&&... __args)
  {
    if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
      {
        _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
                                 std::forward<_Args>(__args)...);
        ++this->_M_impl._M_finish;
      }
    else
      _M_emplace_back_aux(std::forward<_Args>(__args)...);
  }

似乎奇怪的_Reserve(1);是用于VS2013.为什么?

编辑:

所述hex的值-178916020xFEEEFEEE,这意味着

由Microsoft的调试HeapFree()用于标记释放的堆内存

参考幻数

然后我逐行调试上面的代码,发现调用0XFEEEFEEE引起的_Reserve(1);.



1> 1201ProgramA..:

当将元素放入包含该元素的向量时,这是VS2013和VS2015中的问题.如果向量调整大小,则对要插入的元素的引用无效.解决方法是在insert中创建元素的副本,然后插入该元素.

auto n = nums[0];
nums.emplace_back(n);

_Reserve调用用于确保为向量分配了一些内存(因此在以后的操作中不必检查它).


这是一个不幸的设计选择的解决方法.类似的解决方法是`.emplace_back(nums [0] +0)`.从逻辑上讲,添加0不应该改变结果!
@hvd请参阅http://open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2164中的讨论.目前的措辞似乎要求这样做.
推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有