Lars
Lars

Reputation: 13

Type trait to receive T::value_type if present, T otherwise

Required is a type trait for a type T providing a typedef type which is of type T::value_type if T has a typedef value_type, T otherwise.

I have tried the following implementation but it does not seem to work (typedef is always of type T, even if T::value_type is present):

template <class T, class = void> struct value_type { using type = T; };
template <class T> struct value_type<T, typename T::value_type> { using type = typename T::value_type; };

template <class T> using value_type_t = typename value_type<T>::type;

std::is_same_v<value_type_t<int>, int> // true
std::is_same_v<value_type_t<std::optional<int>>, int> // false, should be true

Any idea?

Upvotes: 1

Views: 403

Answers (1)

super
super

Reputation: 12928

The specialization needs to match the base template.

Your base template has class = void, that means the second parameter in your specialization need to be void to match.

The way to do that is to use something like std::void_t, which will become void whatever we put in it. It's only purpose here is to allow SFINAE, if T::value_type is valid we always get void.

template <class T, class = void> struct value_type { using type = T; };
template <class T> struct value_type<T, std::void_t<typename T::value_type>> { using type = typename T::value_type; };

template <class T> using value_type_t = typename value_type<T>::type;

Upvotes: 4

Related Questions