Search code examples
c++c++-concepts

Introduce variable in a C++ constraint


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;
}

Solution

  • 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.