我们知道何时将新元素添加到std :: vector(通过push_back),它可能会缺少空间,在这种情况下,vector分配了更大的内存块来容纳所有元素,然后从现有的块转移到新的元素。在C ++ 98中,这是通过从旧位置复制元素然后销毁那些对象来完成的,因此,它可以提供强大的异常保证,而在c ++ 11中,可以使用move构造函数对其进行优化,前提是不例外,但会发生什么情况如果我的析构函数是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,并且还要注意,如果我将destructor设置为noexcept(默认行为),则只会调用move构造函数。
为了增强对强异常保证的理解(在vector :: push_back中),在成功复制所有内存之前,不会破坏旧内存中的任何元素,这意味着最后将调用析构函数,因此它们是否为noexcept或不
问题在于的规范is_nothrow_move_constructible<T>
,目前已指定该规范以检查表达式是否
T(declval<T&&>())
也不例外,但是涉及(临时的)析构函数以及move构造函数。可以说这是库缺陷,这是正在进行的LWG 2116的主题。GCC正确遵循了规范;规范本身就是不好的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句