Editor/concepts.cpp (41 lines of code) (raw):
// Main simple case
template<class T>
concept Foo = true;
Foo auto func() { return true; }
int main() {
auto f = func(); // warn here to add constraint 'Foo': Foo auto f = func();
Foo auto f1 = func();
auto f2 = f1; // warn here to add constraint 'Foo'
return 0;
}
// Additional cases
template<typename T>
concept MyConcept = requires(T t){ static_cast<bool>(t); };
// 1) Member function in templated struct
template<MyConcept MC>
struct S {
MC func() { return 1; }
};
S<bool> s;
auto s_val = s.func(); // here
// 2) Templated member function
struct S2 {
MyConcept auto func() { return 1; }
};
S2 s2;
auto res = s.func(); // here
// 3) Function pointer (with and without trailing return type)
MyConcept auto (*p)() = func;
auto (*q)() -> auto = p; // here
auto (*r)() = p; // here
// 4) Templated free functions
template<MyConcept MC>
MC func() { return 0; }
auto res2 = func<bool>(); // here
// 5) Concept with several template arguments coming from different places, e.g.:
template<class T, class U, class V>
concept Bar = true;
template<class T>
struct S3 {
template<class U>
Bar<T, U> auto func() { return 1; }
};
S3<int> s3;
auto x = s3.func<char>(); // here
//Completion snippets
template<typename T>
concept CastConcept = requires(T t) {
static_cast<bool>(t);
};