#include // helper metafunctions - just to make the solution self-contained template struct is_same { static const bool value = false; }; template struct is_same { static const bool value = true; }; template struct is_one_of { static const bool value = is_same::value || is_same::value; }; template struct no_common_type_error { typedef T type; }; template struct no_common_type_error { }; template struct multi_and // just syntactic sugar { static const bool value = B0 && B1 && B2 && B3 && B4; }; // tags struct default_t; /* * common_type metafunction */ template< typename T0, typename T1 = default_t, typename T2 = default_t, typename T3 = default_t > struct common_type { private: template struct is_T0_or_default { static const bool value = is_one_of::value; }; static const bool value = multi_and< is_T0_or_default::value, is_T0_or_default::value, is_T0_or_default::value >::value; public: typedef typename no_common_type_error::type type; }; template struct common_type : common_type {}; // exploiting recursion there would be no need of the following cases template struct common_type : common_type {}; template struct common_type { typedef T3 type; }; template<> struct common_type { typedef default_t type; }; /* * tests */ typedef common_type::type C1; typedef common_type::type C2; typedef common_type::type C3; typedef common_type::type C4; typedef common_type::type C5; typedef common_type::type C6; typedef common_type::type C7; // uncomment the following typedef to see error notification messages //typedef common_type::type C8; //typedef common_type::type C9; //typedef common_type::type C10; BOOST_STATIC_ASSERT((is_same::value)); BOOST_STATIC_ASSERT((is_same::value)); BOOST_STATIC_ASSERT((is_same::value)); BOOST_STATIC_ASSERT((is_same::value)); BOOST_STATIC_ASSERT((is_same::value)); BOOST_STATIC_ASSERT((is_same::value)); BOOST_STATIC_ASSERT((is_same::value));