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

Kap*_*pil 2 c++ noexcept c++14

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

\n\n
#include <iostream>\n#include <vector>\n\nclass X\n{\npublic:\n    X()\n    {\n    }\n    X(const X& ob) noexcept\n    {\n      std::cout<<"Copy Constructor...."<<std::endl;\n    }\n    X(X&& ob) noexcept\n    {\n       std::cout<<"Move Constructor...."<<std::endl;\n    }\n    ~X() noexcept(false)\n    {\n    }\n};\nint main()\n{\n   std::vector<X> myobs;\n   for(int i=0;i<1000;i++)\n   {\n      myobs.push_back(X());\n   }\n   return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

为什么在上面的场景中调用复制构造函数,还要注意,如果我将析构函数设置为 noexcept (默认行为),那么只会调用移动构造函数。

\n\n

添加我对强异常保证(在向量::push_back中)的理解是,在成功复制所有元素之前,旧内存中的任何元素都不会被销毁,这意味着析构函数在最后被调用,因此它们是否为 noexcept 并不重要或不

\n

Ker*_* SB 5

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

T(declval<T&&>())
Run Code Online (Sandbox Code Playgroud)

是 noexcept,但这涉及(临时的)析构函数以及移动构造函数。这可以说是一个库缺陷,是正在进行的LWG 2116的主题。GCC正确遵循规范;规范本身是不好的。