本文共 1684 字,大约阅读时间需要 5 分钟。
从C++11开始,我们能看到很多代码当中都有关键字noexcept。比如enable_shared_from_this的构造函数
constexpr enable_shared_from_this() noexcept : _Wptr() { // construct } enable_shared_from_this(const enable_shared_from_this&) noexcept : _Wptr() { // construct (must value-initialize _Wptr) } enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept { // assign (must not change _Wptr) return (*this); }
该关键字告诉编译器,函数中不会发生异常,这有利于编译器对程序做更多的优化。
如果在运行时,noexecpt函数向外抛出了异常(如果函数内部捕捉了异常并完成处理,这种情况不算抛出异常),程序会直接终止,调用std::terminate()函数,该函数内部会调用std::abort()终止程序。C++中的异常处理是在运行时而不是编译时检测的。为了实现运行时检测,编译器创建额外的代码,然而这会妨碍程序优化。
在实践中,一般两种异常抛出方式是常用的:后面这一种方式中在以往的C++版本中常用throw()表示,在C++ 11中已经被noexcept代替。
void swap(Type& x, Type& y) throw() //C++11之前 { x.swap(y); } void swap(Type& x, Type& y) noexcept //C++11 { x.swap(y); }
在第2节中单独使用noexcept,表示其所限定的swap函数绝对不发生异常。然而,使用方式可以更加灵活,表明在一定条件下不发生异常。
void swap(Type& x, Type& y) noexcept(noexcept(x.swap(y))) //C++11 { x.swap(y); }
一个更好的示例是std::pair中的移动分配函数(move assignment),它表明,如果类型T1和T2的移动分配(move assign)过程中不发生异常,那么该移动构造函数就不会发生异常。
pair& operator=(pair&& __p) noexcept(__and_<_T1>, is_nothrow_move_assignable<_T2>>::value) { first = std::forward (__p.first); second = std::forward (__p.second); return *this; }
使用noexcept表明函数或操作不会发生异常,会给编译器更大的优化空间。然而,并不是加上noexcept就能提高效率,步子迈大了也容易扯着蛋。
以下情形鼓励使用noexcept:参考:
转载地址:http://hjiii.baihongyu.com/