David Sankel, in a CppCon 2016 lightning talk, gives as an example the first concept he tried to write:

Personally, the first concept I wrote was true . Your mileage may vary. This concept — a type that you can invoke with any {type that is itself invocable with int and yielding an int }— is, as David pointed out, completely unimplementable* in the Concepts TS. This is because all the expressions that are checked for validity and type must be instances of concrete types. Func is a concrete type, int is a concrete type. But IntFunction isn’t a type, it’s a concept.

What does it mean to specify that a type must be invocable with some other type that satisfies a concept? And how do we check that? We can’t simply try to call Func with the universe of types that satisfy IntFunction . There are an infinite amount of such types, so that’s never going to work. We need to reduce down this infinity to just one representative type of IntFunction . A representative type of a concept is usually called an archetype. Choosing the right archetype is decidedly nontrivial. Let’s go through the process. The standard library comes with a type that models IntFunction , let’s just try it:

This is a start. std::function<int(int)> is certainly an IntFunction , but is this a good archetype of IntFunction ? To answer that question, we have to be more explicit about our goal. We want a say that a type T models concept CallableWithIntFunction if, and only if, for every type M that itself is a model of IntFunction , you can invoke T with an M . The correlating negated definition would be if we can find a type M which models IntFunction , and you cannot invoke T with an M , then T must not model CallableWithIntFunction .

Given that goal, does our implementation succeed? Consider this type:

evil1::C does model CallableWithIntFunction1 , but it doesn’t actually meet our expectations. There are many, many types which would model IntFunction that I couldn’t pass into evil1::C . Just about all of them in fact. So std::function is a bad choice for archetype, we can’t use a well-known class like this. We need our own class type that won’t clash.

Let’s try another implementation, this time with our own private type:

This is better, our evil1::C from before doesn’t model CallableWithIntFunction2 , which is good. But this still isn’t quite right. Consider the following counterexample:

Both of those assertions pass. evil2::F does model IntFunction and evil2::C does model CallableWithIntFunction2 . But… we can’t actually invoke C with an F . Where did we go wrong this time? Again, bad archetype.

Our archetypes::IntFunction is indeed callable with an int , but despite having a body consisting only of a single declaration, it has a lot of other functionality due to the implicit compiler-generated operations. Namely, it’s default constructible, copyable, movable, destructible. None of those operations were things that we checked in IntFunction ! So when we use a function that more narrowly meets the definition, like evil2::F , which is not copyable, our archetype failed us. We have to be far more specific:

With this more restrictive archetype, both evil1::C and evil2::C fail, since both classes require more functionality than IntFunction alone is able to provide. Is this restrictive enough? Still no!

Here, we have a different problem. evil3::F models IntFunction , but that’s probably not what we were expecting. We wanted a function to be callable with an int , but what we actually specified was a function callable with an lvalue of type int . This formulation allows types like evil3::F , which we cannot provide to C .

Let’s try again:

Here now is perhaps the most interesting of cases. evil4::F does model IntFunction : you can invoke it with an int and it does yield a result that is convertible to int . But it doesn’t yield int , so the usage in C isn’t quite valid — passing an evil4::F into an evil4::C will result in a hard error due to the deduction failure for std::min . It may be immediately tempting to restrict IntFunction to specifically yield an int , but that’s far too restrictive to be practically useful. Functions returning something like bool should be acceptable candidates for IntFunction , we don’t want to remove those from consideration. So where did we go wrong?

We did two things wrong. Our archetype is still insufficient, and the user of our concept is misbehaving.

First, our archetype needs to allow for the fact that the call operator can return a type other than int . We’ll just introduce another private type to satisfy that requirement:

Secondly, our evil4::C is misusing the concept IntFunction . All that concept provides for us is that the type is invocable with an int and yields a type that is convertible to int . It does not tell us that the result type is int . Using std::min() in the body makes our function under-constrained. Now, we could go in two directions: either (a) use a more refined concept than IntFunction that stipulates that the return type of the call operator must be precisely int or (b) restrict ourselves to just the functionality that IntFunction provides us. The latter gives us type more opportunities for use, so it’s the better choice here: