標準ライブラリの仕様でnoexcept
が付いているものは、実装にもnoexcept
を付けることが求められます。
しかし、標準ライブラリの仕様でnoexcept
が付いていない場合、実装にnoexcept
を付けないことは求められません。
たとえば、libc++のstd::vector
クラスでは、以下のメンバ関数にnoexcept
が付いています。
vector()
noexcept(is_nothrow_default_constructible<allocator_type>::value);
vector(vector&& x)
noexcept(is_nothrow_move_constructible<allocator_type>::value);
vector& operator=(vector&& x)
noexcept(
allocator_type::propagate_on_container_move_assignment::value ||
allocator_type::is_always_equal::value);
void shrink_to_fit() noexcept;
void swap(vector&)
noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
allocator_traits<allocator_type>::is_always_equal::value);
libstdc++のstd::vector
クラスでは、以下のメンバ関数にnoexcept
が付いています。
vector()
noexcept(is_nothrow_default_constructible<_Alloc>::value);
vector(vector&& __x) noexcept;
vector(vector&& __rv, const allocator_type& __m)
noexcept(_Alloc_traits::_S_always_equal());
vector&
operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move());
void swap(vector& __x) _GLIBCXX_NOEXCEPT;
これにより、特定の標準ライブラリを使用する場合に、例外を投げない強い保証をするコードを書けることがあります (とくにデフォルトコンストラクタが有用)。また、仕様でnoexcept
が付いていない関数に対して、noexcept(式)
で例外を投げないかチェックすることにも意義があります。