正如我们所知,当新元素被添加到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 回答
问题是
is_nothrow_move_constructible<T>
的规范,当前指定是否检查表达式是noexcept,但它涉及析构函数(临时的)以及移动构造函数 . 这可以说是一个图书馆缺陷,正在进行LWG 2116 . GCC遵循规范是正确的;规范本身就是坏事 .