首页 文章

为什么noexcept移动构造函数在向量重新分配期间没有被调用?

提问于
浏览
1

正如我们所知,当新元素被添加到std :: vector(通过push_back)时,它可能缺少空间,并且对于这些情况,vector会分配更大的内存块来保存其所有元素,然后从现有块转移到新块 . 在C 98中,这是通过从旧位置复制元素然后销毁这些对象来完成的,因此它可以提供强大的异常保证,并且在c 11中,它可以使用移动构造函数进行优化,前提是它是noexcept但是如果我的析构函数是noexcept(false)然后为什么没有进行优化?

#include <iostream>
#include <vector>

class X
{
public:
    X()
    {
    }
    X(const X& ob) noexcept
    {
      std::cout<<"Copy Constructor...."<<std::endl;
    }
    X(X&& ob) noexcept
    {
       std::cout<<"Move Constructor...."<<std::endl;
    }
    ~X() noexcept(false)
    {
    }
};
int main()
{
   std::vector<X> myobs;
   for(int i=0;i<1000;i++)
   {
      myobs.push_back(X());
   }
   return 0;
}

为什么在上面的场景中调用了Copy Constructor,并且还注意到如果我将析构函数设置为noexcept(默认行为),那么只会调用移动构造函数 .

为了增加我对强异常保证的理解(在vector :: push_back中),旧内存中的所有元素都不会被破坏,直到所有元素被成功复制,这意味着在末尾调用析构函数,因此无论它们是noexcept还是noexcept都无关紧要 . 不

1 回答

  • 3

    问题是 is_nothrow_move_constructible<T> 的规范,当前指定是否检查表达式

    T(declval<T&&>())
    

    是noexcept,但它涉及析构函数(临时的)以及移动构造函数 . 这可以说是一个图书馆缺陷,正在进行LWG 2116 . GCC遵循规范是正确的;规范本身就是坏事 .

相关问题