#include #include template // make constraints available concept bool C1 = true; template concept bool C2 = true; template concept bool Addition = requires(Type lhs, Type rhs) { lhs + rhs; }; template concept bool Subtraction = requires(Type lhs, Type rhs) { lhs - rhs; }; template // 3rd form: 1st requires introduces requires requires(Type lhs, Type rhs) // the requires-clause, followed { // by the requires expression lhs + rhs; // (which may consist of and/or } // concatenated Type adder(Type lhs, Type rhs) // requires-expressions) { return lhs + rhs; } void fun(int arg) requires requires(int x) { false; }; template concept bool Pack = true; template // multiple void fun2(); template concept bool Constraint = true; template class Data { void process(); }; template requires Constraint class Data; template class Data; template concept bool Concept = true; template struct Struct { Struct() { std::cout << "Generic class template\n"; } Struct(Struct const &other) { std::cout << "Generic class CC\n"; } Struct &operator=(Struct const &other) { std::cout << "Generic operator=\n"; return *this; } Struct &operator+=(Struct const &other) { std::cout << "Generic operator+=\n"; return *this; } }; template struct S2: public Struct { }; template struct Struct; template struct S2; template void fun(); template void fun() requires Addition; template requires Addition void fun(); template // declares a multiply requires C2 void fun(); // constrained function template template // same, using 'and' requires C1 and C2 void fun(); template // same void fun() requires C1 and C2; int main() { // fun(4); // adder(4, 6); // fun2(); // fun2(); // Struct{}; // Struct>{}; S2 s1{}; S2 s2{s1}; s1 = s2; s1 += s2; }