Question

I have several classes. For now they are separated by one symbol. Few of them contains type (a typedef) and few of them doesn't have it.

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

I want to implement a SFINAE class in such a way that,

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

One way is to use basic SFINAE as shown in previous link which checks if the T contains a type and then use a bool checker. For example,

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;
};

Demo.

Question: I have many such instances through out the code and I feel that this method may increase compile-time considerably. Because one has to go through two iterations: 1st for finding type and 2nd through resolving bool flag.

Is there a faster way to achieve to reduce the compile time ?

[Side Note: In this case, I have put type as separator between A and B. However, I am free to put anything inside A which will separate it from B. Ideas related to that are also welcome.]

Was it helpful?

Solution

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;
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top