#include <iostream>
#include <utility>
#include <type_traits>

    namespace details {
      template<class...>struct types{using type=types;};
      template<class U, class Types, class=void>
      struct smart_cast_t:std::false_type {
        using type=U;
        template<class A>
        U operator()(A&& a)const{return std::forward<A>(a);}
      };
      template<class U, class T0, class...Ts>
      struct smart_cast_t<
        U, types<T0, Ts...>,
        typename std::enable_if<std::is_convertible<U, T0>::value>::type
      >:std::true_type
      {
        using type=T0;
        template<class A>
        T0 operator()(A&& a)const{return std::forward<A>(a);}
      };
      template<class U, class T0, class...Ts>
      struct smart_cast_t<
        U, types<T0, Ts...>,
        typename std::enable_if<!std::is_convertible<U, T0>::value>::type
      >:smart_cast_t< U, types<Ts...> >
      {};
    }
    
    template<class... Ts, class U>
    auto smart_cast( U&& u )
    -> decltype(details::smart_cast_t< U, details::types<Ts...> >{}( std::forward<U>(u) ))
    {
      return details::smart_cast_t< U, details::types<Ts...> >{}( std::forward<U>(u) );
    }

int main() {
	std::cout << smart_cast< char, double >( int('a') ) << "\n";
	std::cout << smart_cast< double, char >( int('a') ) << "\n";
	// your code goes here
	return 0;
}