+1 Though I'd recommend using std::ranges::sort in the body, so readers don't think they need to do this themselves by mistake.

On Sat, Feb 29, 2020 at 6:32 PM Tony V E <tvaneerd@gmail.com> wrote:
I've just started on a quick explanation of concepts: https://github.com/tvaneerd/cpp20_in_TTs/blob/master/concepts.md

I went with

void sort(std::ranges::random_access_range auto & c)
    std::sort(c.begin(), c.end());

The definition of random_access_range might be a bit ugly to look at, but the idea is simple - if you don't have random access you probably want to sort a different way.

On Sat, Feb 29, 2020 at 8:42 PM Christopher Di Bella via SG20 <sg20@lists.isocpp.org> wrote:
Concepts exist primarily to express requirements on algorithms. I would recommend doing your best to introduce them in a light that reflects this first and foremost. If your foo can work with any integral, but requires some integral, then it could potentially be a candidate. Although I haven't tried what I'm about to suggest, I can see the use of foo potentially being a good way forward for introducing templates too: when showing that multiple overloads that are textually identical otherwise is cumbersome and error-prone, foo(std::integral auto) is the solution for integrals (and don't show full template syntax for a while).

I certainly recommend deferring the design of concepts for a long while, and to come up with a genuine use-case before showing them off.

template<typename T>
concept has_size = requires(T t) { t.size(); }; // BAD

In general, although simple, a concept that starts with has_ is probably not good to show off at all (unless you're showing it as an anti-pattern).

On Sat, 29 Feb 2020, 17:22 Amir Kirsh via SG20, <sg20@lists.isocpp.org> wrote:
A short intro
When teaching a feature I'm always trying to bring the minimal example that is still a good one in terms of best practices. I'm trying to avoid minimal examples that are convincing but rely on bad practice that might be adopted by the students.

now to concepts
One of the minimal first examples that can be given with concepts is:
void foo(std::integral auto number) { /* */ }
As a substitute for:
void foo(long number) { /* */ }
But then I'm a bit reluctant. Is it really a proper substitute? The two are not the same. What are the pros and cons of having a template function, avoiding type conversion, compared to a simple function? Is it a good example or a misuse? In which cases this is a good substitute? 

I tried to raise this question in SO but didn't get much support for it:

This is not a yes/no question - I do believe things might be a pro in one case and a con in another. Analyzing the pros and cons for different use cases can surely assist in understanding the proper choice per each case.
As a teacher I believe this is important, even if not discussed in class, to understand the pros and cons.
(If there are only pros than the example becomes a new "best practice". And if there are only cons it becomes an "anti-pattern". I think above is neither, it probably has good and bad use cases which worth understanding).

Would appreciate your thoughts (on the specific matter, as well as opinions on understanding pros and cons as a teaching requisite, i.e. is this a relevant question in your opinion).


SG20 mailing list
SG20 mailing list

Be seeing you,