考虑一个函数f,欲向调用方保证它不会抛出异常:
int f(int x) throw(); // C++98
int f(int x) noexcept; // C++11
在带有 noexcept
声明的函数中,优化器不需要在异常传出函数的前提下保证所有其中的对象以其被构造的顺序的逆序完成析构,而 throw()
声明的函数则享受不到这样的优化灵活性。
执行 std:::vector
的 push_back()
成员函数时,如果对象的尺寸和容量相等时,就需要扩容。C++98的做法是开辟一块更大的内存,将原有内存拷贝到新内存中,这样的做法可以保证复制过程中如果出现异常,可以退会初始状态(全有或全无),这样保证了强异常安全性。C++11引入移动语义后,更有效率的做法应当是将原有内存移动到新内存中。然而如果移动抛出异常,则也无法保证移动回原有内存不会抛出异常,这样就无法保证强异常安全了。
std::vector::push_back
利用了“能移动就移动,必须复制才复制的策略”,仅在移动操作不会抛出异常的情况下选择移动策略。方法是检测移动操作是否带有 noexcept
声明。
noexcept
性质对于移动操作,swap,内存释放函数和析构函数最有价值。
大多数函数都是异常中立的,不具备 noexcept
性质。