正如 Scott Meyers 所指出的(http://channel9.msdn.com/Events/GoingNative/2013/An-Effective-Cpp11-14-Sampler 在 00.34.45)只有当一个类的移动函数被声明为非抛出(最好使用 noexcept)并且只有这样,vector::push_back() 才能使用移动语义。
那么类的编译器生成的移动函数的异常规范是什么?如果没有提供强大的异常保证,是否意味着我无法从 C++11 push_back() 和其他类似方法中的移动语义中获得优化?
最佳答案
隐式生成的移动(以及隐式拷贝和继承的构造函数)的异常规范在 15.4/14 中有详细说明:
An inheriting constructor (12.9) and an implicitly declared special member function (Clause 12) have an exception-specification. If
f
is an inheriting constructor or an implicitly declared default constructor, copy constructor, move constructor, destructor, copy assignment operator, or move assignment operator, its implicit exception-specification specifies the type-idT
if and only ifT
is allowed by the exception-specification of a function directly invoked byf
’s implicit definition;f
allows all exceptions if any function it directly invokes allows all exceptions, andf
has the exception-specificationnoexcept(true)
if every function it directly invokes allows no exceptions. [ Note: It follows thatf
has the exception-specificationnoexcept(true)
if it invokes no other functions. —end note ] [ Note: An instantiation of an inheriting constructor template has an implied exception-specification as if it were a non-template inheriting constructor. —end note ]
哇哦。
因此,编译器有效地将您的类的隐式移动声明为可能抛出每个成员智能移动声明抛出的任何异常的并集。如果它们都是 noexcept
,则您类(class)的着法也是 noexcept
。
你是对的,当类型是可复制的并且它的移动操作可能会抛出时,vector
重新分配之类的东西将更愿意复制该类型。出于这个原因,为 noexcept
移动您计划存储在容器中的类的构造和分配进行设计是一个非常好的主意。
关于c++ - 异常保证和快速 push_back,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21653598/