Более короткий способ определения типа в классе :: typedef - PullRequest
4 голосов
/ 06 октября 2011

У меня есть несколько классов.Пока они разделены одним символом.Немногие из них содержат type (a typedef), и немногие из них не имеют его.

struct A { ... public: typedef someclass type; }
struct B { ... };

Я хочу реализовать класс SFINAE таким образом, чтобы,

Resolve<A>::type o1;  // should resolve to 'A::type'
Resolve<B>::type o2;  // should resolve to 'B'

Один из способов - использовать базовую SFINAE, как показано в предыдущей ссылке, которая проверяет, содержит ли T type, а затем использовать проверку bool.Например,

template <typename T>
struct has_type {
  typedef char yes[3];
  template <typename C> static yes& test(typename C::type*);
  template <typename> static char& test(...);
  static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};

template<typename TYPE, bool = has_type<TYPE>::value>
struct Contains { typedef typename TYPE::type type; };
template<typename TYPE>
struct Contains<TYPE, false> { typedef TYPE type; };

template<class TYPE>
struct Resolve {
  typedef typename Contains<TYPE>::type type;
};

Демо .

Вопрос : у меня есть много таких примеров в коде, и я чувствую, что этот метод можетзначительно увеличить время компиляции.Потому что нужно пройти две итерации: 1-ю для нахождения type и 2-ю для разрешения bool флага.

Есть ли более быстрый способ , чтобы сократить время компиляции?

[Примечание: в этом случае я поместил type в качестве разделителя между A и B.Тем не менее, я могу свободно поместить что-либо в A, что отделит его от B.Также приветствуются идеи, связанные с этим.]

1 Ответ

3 голосов
/ 06 октября 2011
template<typename>
struct void_ {
    typedef void type;
};

template<typename T, typename = void>
struct Resolve {
    typedef T type;
};

template<typename T>
struct Resolve <T, typename void_<typename T::type>::type> {
    typedef typename T::type type;
};
...