, smart Ts..., Ts..., , :
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) );
}
, foo :
void foo_impl(X);
void foo_impl(Y);
template<class A>
void foo(A&& a) {
foo_impl( smart_cast<X, Y>(std::forward<A>(a)) );
}
foo, , A X, Y.
, foo types< types<X,Y> > foo , , .
++ 11. ++ 14 smart_cast.
. types ( ).
details::smart_cast_t , U U. U , . , , .
, - smart_cast< type1, type2, type3, etc >( expression ). U , , .
: - , .
, , . static_cast<T0> - smart_cast_t, .
smart_cast_t true_type false_type . , smart_cast_t<U, types<Ts...>>::value , U Ts..., U.
rvalue vs lvalue. , a U a U&&, r. - U - , , , smart_cast<int, double>(std::string("hello")) std::string, operator() smart_cast_t.
, smart_cast<int, double>(""). - typename std::decay<U>::type - .