Given a require block on a struct such as this one
template<typename A, typename B, typename C>
struct MyOtherTypeLevelFunction<A, B, C>;
template<typename A, typename B, typename C> requires
(MyConcept<MyTypeLevelFunction<A, B, C>>)
&& (MyOtherConcept<MyTypeLevelFunction<A, B, C>>)
struct MyOtherTypeLevelFunction<A, B, C> {
using Output = MyTypeLevelFunction<A, B, C>::T;
}
Is is possible to introduce a variable to avoid repeating calls to MyTypeLevelFunction? Ideally both in the requires block and the structure body. I tried the following, but it fails with Default template argument in a class template partial specialization.
template<typename A, typename B, typename C>
struct MyOtherTypeLevelFunction<A, B, C>;
template<typename A, typename B, typename C, typename X = MyTypeLevelFunction<A, B, C>> requires
(MyConcept<X>)
&& (MyOtherConcept<X>)
struct MyOtherTypeLevelFunction<A, B, C> {
using Output = X::T;
}
CodePudding user response:
You can create a combined concept:
template <typename F>
concept MyCombinedConcept = MyConcept<F> && MyOtherConcept<F>;
template<typename A, typename B, typename C>
requires MyCombinedConcept<MyTypeLevelFunction<A, B, C>>
struct MyOtherTypeLevelFunction<A, B, C> {
using Output = MyTypeLevelFunction<A, B, C>::T;
}
and optionally put MyCombinedConcept in a detail namespace if it's an implementation detail.
CodePudding user response:
Even if a default template argument worked, it would be uncool, because it can be overriden by user.
You can do this:
template <typename A, typename B, typename C>
requires requires(MyTypeLevelFunction<A, B, C> x)
{
requires MyConcept<decltype(x)> && MyOtherConcept<decltype(x)>;
}
struct MyOtherTypeLevelFunction<A, B, C>
{
using Output = MyTypeLevelFunction<A, B, C>::T;
};
