
Juraj Ivančić wrote:
Eric Niebler wrote:
I recently had a C++ problem and found an answer that tickled my brain. In the spirit of Car Talk on NPR, I thought I'd share it in the form of a puzzler.
Here is my solution. Not sure that it satisfies the conditions though.
Here I added a minor improvement which did not occur to me until reading latest solutions from Daniel Frey. Regards, Juraj Ivančić #include "boost/static_assert.hpp" #include "boost/type_traits/is_same.hpp" #include "boost/mpl/if.hpp" class ErrorFoundTwoNonDefaultTypes {}; class Default {}; template<typename T1, typename T2> struct FindNonDefault { typedef typename boost::mpl::if_ < boost::is_same<T1, Default>, T2, typename boost::mpl::if_ < boost::is_same<T2, Default>, T1, ErrorFoundTwoNonDefaultTypes >::type >::type type; }; template<typename T1, typename T2> struct DetermineCommonBetweenTwo { typedef typename boost::mpl::if_ < boost::is_same<T1, T2>, T1, typename FindNonDefault<T1, T2>::type >::type type; }; template < typename T1 , typename T2 = Default, typename T3 = Default, typename T4 = Default, typename T5 = Default, typename T6 = Default, typename T7 = Default, typename T8 = Default
struct DetermineCommon { typedef typename DetermineCommonBetweenTwo < typename DetermineCommonBetweenTwo < typename DetermineCommonBetweenTwo<T1,T2>::type, typename DetermineCommonBetweenTwo<T3,T4>::type >::type, typename DetermineCommonBetweenTwo < typename DetermineCommonBetweenTwo<T5,T6>::type, typename DetermineCommonBetweenTwo<T7,T8>::type >::type >::type type; }; //-------------------- class A {}; class B {}; BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<Default, Default, Default, Default>::type, Default >::value )); BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<A , A , Default, A >::type, A >::value )); BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<A , Default, Default, A >::type, A >::value )); BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<Default, A >::type, A >::value )); BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<Default, A , Default, A >::type, A >::value )); BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<A , B >::type, ErrorFoundTwoNonDefaultTypes>::value )); BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<A , Default, B >::type, ErrorFoundTwoNonDefaultTypes>::value )); BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<A , Default, Default, B >::type, ErrorFoundTwoNonDefaultTypes>::value )); BOOST_STATIC_ASSERT(( boost::is_same<typename DetermineCommon<A , B , Default >::type, ErrorFoundTwoNonDefaultTypes>::value )); //-------------------- int main() { return 0; }