標準ライブラリの仕様でnoexcept
が付いているものは、実装にもnoexcept
を付けることが求められます。
しかし、標準ライブラリの仕様でnoexcept
が付いていない場合、実装にnoexcept
を付けないことは求められません。
たとえば、libc++のstd::vector
クラスでは、以下のメンバ関数にnoexcept
が付いています。
// https://github.com/llvm-mirror/libcxx/blob/018a3d51a47f7275c59e802709104498b729522b/include/vector 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
が付いています。
// https://github.com/gcc-mirror/gcc/blob/67886b40399e79bcc392a152e96d9116ba24e2ed/libstdc%2B%2B-v3/include/bits/stl_vector.h 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()); // swapで例外を投げそうなアロケータはコンパイルエラー void swap(vector& __x) _GLIBCXX_NOEXCEPT;
これにより、特定の標準ライブラリを使用する場合に、例外を投げない強い保証をするコードを書けることがあります (とくにデフォルトコンストラクタが有用)。また、仕様でnoexcept
が付いていない関数に対して、noexcept(式)
で例外を投げないかチェックすることにも意義があります。