namespace details{
template<template<class...> class, class, class...>
struct can_apply : std::false_type{};
template<template<class...> class Z, class...Ts>
struct can_apply<Z, std::void_t<Z<Ts...>>, Ts...> : std::true_type{};
}
template<template<class...> class Z, class...Ts>
using can_apply = details::can_apply<Z, void, Ts...>;
template<class T>
using dot_toString_r = decltype(std::declval<T>().toString());
template<class T>
using can_dot_toString = can_apply<dot_toString_r, T>;
I leave can_std_to_string
as an exercise.
If you are missing void_t
the standard version:
template<class...> struct voider { using type=void; };
template<class...Ts> using void_t = typename voider<Ts...>::type;
What works even in the early C ++ 11.
source
share