Can we have an alias template that points to a type if a constraint is false, or to another type if that constraint is true ?
template < class T >
using MyType = SomeType;
template < class T >
requires SomeConstraint
using MyType = SomeOtherType;
I know doing it this way doesn't compile but is there a workaround ? Because I want to have some types in a class that are set to void
if a constraint is not respected, or to something else if the constaint is respected without having to make the whole class require that constraint
CodePudding user response:
Yes, either by moving the alias into a class and partially specializing the class (and then aliasing the alias in the class from the outside), or for the case you are showing simpler:
template<typename T>
using MyType = std::conditional_t<requires{ requires SomeConstraint; },
SomeOtherType, SomeType>;
Depending on what SomeConstraint
is (I am assuming it to be a placeholder for something more complex than an identifier) probably also just
template<typename T>
using MyType = std::conditional_t<SomeConstraint,
SomeOtherType, SomeType>;
will be fine.
In either case this will require however that both SomeOtherType
and SomeType
are valid types (again assuming these are placeholders). It will not apply SFINAE to them. If that is not given you need to fall back to the class partial specialization method.
The class template partial specialization method:
template<typename T>
struct MyTypeImpl {
using type = SomeType;
};
template<typename T>
requires SomeConstraint
struct MyTypeImpl<T> {
using type = SomeOtherType;
};
template<typename T>
using MyType = typename MyTypeImpl<T>::type;