I wonder how to conditionally set a type alias, based on the existance of a type alias in input argument like this.
struct a { using type = int; }
template <typename T> struct wrapper {
using inner_t = ???how???; // if T::type exists, use T::type, else T
};
static_assert(std::is_same<wrapper<int>::inner_t, int>, "expected int");
static_assert(std::is_same<wrapper<a>::inner_t, int>, "expected inner type: int");
One naive attempt is like std::conditional<std::is_class<T>, T::type, T>
if the existence of a type
alias is a prerequisite, but is far from being safe, lacking a check for something like is_alias_present<T, type>
. Besides that T::type
is potentially not existing for all types resulting in a compiler error.
Apearently std::experimental::is_detected looks promising, but unfortunately not an option for now.
Not sure if metaprogramming libraries like boost::mp11
or boost::hana
are a good approach to get that done.
There are 2 things, the traits to detect presence, and the lazy evaluation.
In C++20, the traits can be done easily with requires
template <typename T>
concept has_type = requires { typename T::type; }
Then the lazy evaluation:
template <typename T> struct wrapper {
using inner_t = std::conditional_t<has_type<T>, T, std::type_identity<T> >::type;
};