Just use std::void_t
(or a C++11 alternative):
template<typename T, typename = std::void_t<>>
struct ChooseIfType : std::false_type {};
template<typename T>
struct ChooseIfType<T, std::void_t<typename T::Type>> : std::true_type {};
live demo
The solution makes use of SFINAE. The default is never malformed and creates a trait with value false. The compiler tries to match all template specializations (only one in this case). If T
has a member type Type
, then ChooseIfType<T, void_t<typename T::Type>>
is more specialized than ChooseIfType<T, void_t<>>
. If it doesn't, then it's not a viable specialization and the default is selected, but Substitution Failure Is Not An Error.
as per cppreference, a C++11 void_t
implementation could look like this:
template<typename... Ts> struct make_void { typedef void type;};
template<typename... Ts> using void_t = typename make_void<Ts...>::type;