Partial specialization of typedef

I want to have a type which is either a typedef or a class. Thus, something like this

template< typename T > class A { };
template< typename T > using X< T, true > = T;
template< typename T > using X< T, false > = A< T >;

Obviously, this does not compile.

To overcome this problem I "invented" the following construct, which seems quite complicated in my eyes:

template< typename T > class A { }; 

template< typename T, bool E > struct make_X;

template< typename T >
struct make_X< T, true > {
    T make();
};

template< typename T >
struct make_X< T, false > {
    A< T > make();
};

template< typename T, bool E > using X = decltype( make_X<T,E>::make() );

Is there an easier way to achieve my goal?


Normally, one would do this:

template< typename T, bool E > using X = std::conditional_t<E, T, A<T>>;

The only issue here would be if you wanted to use the type X<T, true> in a situation where simply mentioning A<T> would be ill-formed. In that case X<T, true> will be ill-formed even though the result is not A<T> anyway. If this is a possible situation, then something more complicated, like what you wrote, could be appropriate in order to make sure that A<T> is never even mentioned in the first place. However, in general, this would be done using type aliases in the partial specializations (e.g. using type = T;) and not through functions, in case T or A<T> is some kind of type that is not allowed as a function return type.