を少し実装してみた
C++0xの
そこで、GCC4.6.0(20110122)を使い、未実装のメタ関数を3つ実装してみました。trivially系はコンパイラのサポートが必要だと思われるので、それ以外から選ぶことにして、is_move_constructible、is_destructible、is_nothrow_destructibleを実装します。
まず、is_move_constructibleを実装します。is_constructibleが提供されているので、それを利用します。
template <class T, bool IsVoid = std::is_void<T>::value> struct is_move_constructible : std::is_constructible<T, T &&> {}; template <class T> struct is_move_constructible<T, true> : std::false_type {};
これに限らず、ほとんどのtype propertyは、complete typeに加えてvoidとarray of unknown boundを受け入れなければなりません。今回はT &&があるので、voidだけ特殊化で切り分けます。(add_rvalue_referenceを使っても良い?)
次にis_destructibleですが、これは一から作らなければなりません。SFINAEを使います。
template <class T> struct test { T t; }; template <class T, class = void> struct is_destructible_impl : std::false_type {}; template <class T> struct is_destructible_impl<T, decltype(std::declval<test<T>>().~test())> : std::true_type {}; template <class T, bool IsVoid = std::is_void<T>::value> struct is_destructible : is_destructible_impl<T> {}; template <class T> struct is_destructible<T, true> : std::false_type {}; template <class T> struct is_destructible<T [], false> : std::false_type {};
test
最後にis_nothrow_destructibleを実装します。noexcept演算子を使います。
template <class T, bool IsDestructible = is_destructible<T>::value> struct is_nothrow_destructible : std::false_type {}; template <class T> struct is_nothrow_destructible<T, true> : std::integral_constant<bool, noexcept(std::declval<test<T>>().~test())> {};
自動生成されたtest
今回は3つだけ実装しましたが、他のメタ関数も同じように実装できると思います。