4

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.]

iammilind
  • 68,093
  • 33
  • 169
  • 336

1 Answers1

3
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;
};
iammilind
  • 68,093
  • 33
  • 169
  • 336
Luc Danton
  • 34,649
  • 6
  • 70
  • 114
  • Good one. You are very fast. I feel this code is **at least** better than what I wrote. Let see if someone else offer better. – iammilind Oct 06 '11 at 06:37
  • @iammilind As a warning you should make sure the code works on your end, this needs good SFINAE support. – Luc Danton Oct 06 '11 at 06:39
  • I din't get you. Is your kind of SFINAE not supported by all compilers ? In that case should I put `#ifdef #else #endif` ? – iammilind Oct 06 '11 at 06:44
  • 2
    @iammilind I actually don't know if it's allowed in C++03 or not. I know it's allowed in C++11 but keep in mind that standard has clarified some points on SFINAE (a.k.a 'extended SFINAE'). While I'm an avid user of SFINAE I really have no idea what the exact rules for C++03 are and I don't recommend you try learning them :) – Luc Danton Oct 06 '11 at 06:54