Home > OS >  Introduce variable in a C constraint
Introduce variable in a C constraint

Time:01-27

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;
};
  •  Tags:  
  • Related