简体   繁体   中英

How to specialize a type based on whether a template parameter has an alias

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!

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM