Boostのソースを解析してType Traitsを作成中
労を惜しまずに作ればこうなる
template <typename Type> struct is_void { enum { value = 0 }; }; template <> struct is_void<void> { enum { value = 1 }; };
でもめんどくさいので
こういう簡単に特殊化できるようにするマクロを作って
template <typename Type, Type Value> struct integral_constant { static const Type value = Value; typedef Type value_type; }; typedef integral_constant<bool, true> true_type; typedef integral_constant<bool, false> false_type; // 指定された型を特殊化 #define SHAND_TRAITS_SPEC0(Spec, Value) \ template <> \ struct Spec : public integral_constant<bool, Value> {}; #define SHAND_TRAITS_SPEC1(Spec, Value) \ template <typename Type> \ struct Spec : public integral_constant<bool, Value> {}; #define SHAND_TRAITS_SPEC2(Spec, Value) \ template <typename Type, typename ClassName> \ struct Spec : public integral_constant<bool, Value> {}; // Type, Type const, Type volatile, Type const volatileの4つを一気に特殊化 #define SHAND_TRAITS_SPEC(Order, Traits, SpecialType, Value) \ SHAND_TRAITS_SPEC##Order##(Traits<SpecialType>, Value) \ SHAND_TRAITS_SPEC##Order##(Traits<SpecialType const>, Value) \ SHAND_TRAITS_SPEC##Order##(Traits<SpecialType volatile>, Value) \ SHAND_TRAITS_SPEC##Order##(Traits<SpecialType const volatile>, Value)
こう使う
// is_void : void型 template <typename Type> struct is_void : public false_type {}; SHAND_TRAITS_SPEC(0, is_void, void, true) // is_integral : 整数型 template <typename Type> struct is_integral : public false_type {}; SHAND_TRAITS_SPEC(0, is_integral, bool, true) SHAND_TRAITS_SPEC(0, is_integral, char, true) SHAND_TRAITS_SPEC(0, is_integral, signed char, true) SHAND_TRAITS_SPEC(0, is_integral, unsigned char, true) SHAND_TRAITS_SPEC(0, is_integral, wchar_t, true) SHAND_TRAITS_SPEC(0, is_integral, short, true) SHAND_TRAITS_SPEC(0, is_integral, unsigned short, true) SHAND_TRAITS_SPEC(0, is_integral, int, true) SHAND_TRAITS_SPEC(0, is_integral, unsigned int, true) SHAND_TRAITS_SPEC(0, is_integral, long, true) SHAND_TRAITS_SPEC(0, is_integral, unsigned long, true) SHAND_TRAITS_SPEC(0, is_integral, long long, true) SHAND_TRAITS_SPEC(0, is_integral, unsigned long long, true) // is_float : 浮動小数点型 template <typename Type> struct is_float : public false_type {}; SHAND_TRAITS_SPEC(0, is_float, float, true) SHAND_TRAITS_SPEC(0, is_float, double, true) SHAND_TRAITS_SPEC(0, is_float, long double, true)
// is_reference : 参照型 template <typename Type> struct is_reference : public false_type {}; template <typename Type> struct is_reference<Type&> : public true_type {}; // is_pointer : ポインタ型 template <typename Type> struct is_pointer : false_type {}; SHAND_TRAITS_SPEC(1, is_pointer, Type*, true)
マクロは忘れずに消しましょう
#undef SHAND_TRAITS_SPEC0 #undef SHAND_TRAITS_SPEC1 #undef SHAND_TRAITS_SPEC2 #undef SHAND_TRAITS_SPEC
サンプル
#include <iostream> #include <shand/type_traits.hpp> using namespace std; using namespace shand; int main() { // intが整数だったら1、整数じゃなかったら0 cout << is_integral<int>::value << endl; return 0; }
そしてさらにめんどくさいのでVC++6.0には非対応
Boostはとても勉強になります
参考サイト
Boost - Type Traits(型特性)