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.