formalizing a concept with conditional requirements

Well, that was strangely easy.

#include <concepts>
#include <cstddef>
#include <type_traits>

template<int N, template<int> class X>
concept Fooable =
requires(X<N> a, int i) { a[i]; } &&
(
    N == 1 ||
    requires(X<N> a) { a.reduce(); }
);

template<int N, template<int> class X>
requires Fooable<N, X>
void foo(X<N>) {}

template<int N>
struct Myx1 {
    int operator[](int) { return 0; };
};

template<int N>
struct Myx2 {
    int operator[](int) { return 0; }
    int reduce() { return 0; }
};

int main() {
    foo(Myx1<1>{});
    foo(Myx1<2>{}); // error - no reduce() and N != 1
    foo(Myx2<2>{});
}

The || operator in concepts is short-circuiting, just like normal operator, so N == 1 || something works as expected.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top