2013年12月18日水曜日

gcc2.7.2でis_enumを実装したかった・・・

どうしてもコンパイラ警告が消えないので、諦めモード・・・。
SFINAEとか使えないのが痛すぎる。


■現下の実装
template <typename T> struct is_primitive { enum { value = 0 }; };
template <> struct is_primitive<void> { enum { value = 1 }; };
template <> struct is_primitive<bool> { enum { value = 1 }; };
template <> struct is_primitive<int> { enum { value = 1 }; };
template <> struct is_primitive<unsigned int> { enum { value = 1 }; };
template <> struct is_primitive<char> { enum { value = 1 }; };
template <> struct is_primitive<signed char> { enum { value = 1 }; };
template <> struct is_primitive<unsigned char> { enum { value = 1 }; };
template <> struct is_primitive<short> { enum { value = 1 }; };
template <> struct is_primitive<unsigned short> { enum { value = 1 }; };
template <> struct is_primitive<long> { enum { value = 1 }; };
template <> struct is_primitive<unsigned long> { enum { value = 1 }; };
template <> struct is_primitive<float> { enum { value = 1 }; };
template <> struct is_primitive<double> { enum { value = 1 }; };

typedef char yes_type;
struct no_type { char dummy[8]; };
yes_type enum_check(int);
no_type  enum_check(...);

template <typename T>
struct is_enum_impl
{
  enum
  {
    value1 = (sizeof(yes_type) == sizeof(enum_check(*((T*)0)))),
    value2 = !is_primitive<T>::value,
    value3 = value1 && value2
  };
};

template <typename T>
struct is_enum
{
  enum
  {
    value = is_enum_impl<T>::value3
  };
};
■出る警告
warning: cannot pass objects of type `(構造体/クラス名)' through `...'

■ダメな実装
(1) template <typename T> no_type check(T*, void (T::*)() = 0);
(2) yes_type check(...);
とか書くと、enumの型で(1)が適用される。

0 件のコメント:

コメントを投稿