#include #include struct D {}; // default type template< typename T0, typename T1, typename T2 > struct common_type { template< typename T > static T x( D*, D*, T* ); template< typename T > static T x( D*, T*, D* ); template< typename T > static T x( D*, T*, T* ); template< typename T > static T x( T*, D*, D* ); template< typename T > static T x( T*, D*, T* ); template< typename T > static T x( T*, T*, D* ); template< typename T > static T x( T*, T*, T* ); typedef __typeof__( x( (T0*)0, (T1*)0, (T2*)0 ) ) type; }; template<> struct common_type< D, D, D > { typedef D type; }; int main() { std::cout << typeid( common_type< D, D, D >::type ).name() << std::endl; std::cout << typeid( common_type< D, int, D >::type ).name() << std::endl; std::cout << typeid( common_type< bool, bool, bool >::type ).name() << std::endl; // std::cout << typeid( common_type< D, char, double >::type ).name() << std::endl; }