0

I want to be able to specialize a type based on whether a container has a specified typedef for example

class SomethingElse {};
class Something {
    using Type = int;
};

static constexpr bool value = ChooseIfType<Something>::value;

Is there a way for ChooseIfType to return false when the type does not have the typedef Type?

I feel like there is an easy way to do this but I cannot figure it out.

Thanks!

Curious
  • 20,870
  • 8
  • 61
  • 146

1 Answers1

2

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;
krzaq
  • 16,240
  • 4
  • 46
  • 61
  • Could you explain how that is working? What happens when the default substitution for void_t is malformed? – Curious Oct 27 '16 at 03:16
  • @Curious Is that to your liking? – krzaq Oct 27 '16 at 03:23
  • But both `void_t<>` and `void_t` are the same right? As per http://en.cppreference.com/w/cpp/types/void_t – Curious Oct 27 '16 at 03:26
  • @Curious both yield `void`, yes. Maybe look at this answer for futher details http://stackoverflow.com/questions/27687389/how-does-void-t-work – krzaq Oct 27 '16 at 03:27
  • Thanks! That makes it clear. So its only because the void_t with the specialization is "more specialized" – Curious Oct 27 '16 at 03:30