Date: Sun, 1 Mar 2020 08:11:23 +0200
Substitute I mean not as a replacement for existing code. But rather: now
you can write instead *that*, in new code.
So again the question is if (or when) the use of *std::integral* would be
actually advisable over let's say *long long*.
Or what are the pros and cons.
For example:
The obvious case: if this function needs to get the number parameter as an
lvalue reference, the concept (template) approach is valid and the simple
one is not.
Then: what are the cases in which preserving the original type is a pro?
Are there any performance advantages for one of the two in certain cases?
Is one safer than the other in a way?
בתאריך יום א׳, 1 במרץ 2020, 6:44, מאת Yehezkel Bernat via SG20 <
sg20_at_[hidden]>:
> For the original example, I'd say this is a good example only if the
> source was a template, or an overload set as suggested by Chris. If the
> function was just fine with taking the widest integral type (probably `long
> long` was a better choice?) and relaying on integral promotion from
> whatever the caller sent, there is probably no reason to make it a
> template, even if by using a concept.
>
> If it was a template (or a good candidate to become one), then yes,
> putting a constraint on it to express its requirements is a good usage of
> concepts.
>
> On Sun, Mar 1, 2020, 4:35 AM Christopher Di Bella via SG20 <
> sg20_at_[hidden]> wrote:
>
>> +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_at_[hidden]> 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_at_[hidden]> 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_at_[hidden]>
>>>> 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:
>>>>>
>>>>> https://stackoverflow.com/questions/60470216/how-much-is-too-much-with-c20-concepts (SO
>>>>> question has an additional example inside).
>>>>>
>>>>> 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).
>>>>>
>>>>> Amir
>>>>>
>>>>> --
>>>>> SG20 mailing list
>>>>> SG20_at_[hidden]
>>>>> https://lists.isocpp.org/mailman/listinfo.cgi/sg20
>>>>>
>>>> --
>>>> SG20 mailing list
>>>> SG20_at_[hidden]
>>>> https://lists.isocpp.org/mailman/listinfo.cgi/sg20
>>>>
>>>
>>>
>>> --
>>> Be seeing you,
>>> Tony
>>>
>> --
>> SG20 mailing list
>> SG20_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/sg20
>>
> --
> SG20 mailing list
> SG20_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg20
>
you can write instead *that*, in new code.
So again the question is if (or when) the use of *std::integral* would be
actually advisable over let's say *long long*.
Or what are the pros and cons.
For example:
The obvious case: if this function needs to get the number parameter as an
lvalue reference, the concept (template) approach is valid and the simple
one is not.
Then: what are the cases in which preserving the original type is a pro?
Are there any performance advantages for one of the two in certain cases?
Is one safer than the other in a way?
בתאריך יום א׳, 1 במרץ 2020, 6:44, מאת Yehezkel Bernat via SG20 <
sg20_at_[hidden]>:
> For the original example, I'd say this is a good example only if the
> source was a template, or an overload set as suggested by Chris. If the
> function was just fine with taking the widest integral type (probably `long
> long` was a better choice?) and relaying on integral promotion from
> whatever the caller sent, there is probably no reason to make it a
> template, even if by using a concept.
>
> If it was a template (or a good candidate to become one), then yes,
> putting a constraint on it to express its requirements is a good usage of
> concepts.
>
> On Sun, Mar 1, 2020, 4:35 AM Christopher Di Bella via SG20 <
> sg20_at_[hidden]> wrote:
>
>> +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_at_[hidden]> 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_at_[hidden]> 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_at_[hidden]>
>>>> 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:
>>>>>
>>>>> https://stackoverflow.com/questions/60470216/how-much-is-too-much-with-c20-concepts (SO
>>>>> question has an additional example inside).
>>>>>
>>>>> 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).
>>>>>
>>>>> Amir
>>>>>
>>>>> --
>>>>> SG20 mailing list
>>>>> SG20_at_[hidden]
>>>>> https://lists.isocpp.org/mailman/listinfo.cgi/sg20
>>>>>
>>>> --
>>>> SG20 mailing list
>>>> SG20_at_[hidden]
>>>> https://lists.isocpp.org/mailman/listinfo.cgi/sg20
>>>>
>>>
>>>
>>> --
>>> Be seeing you,
>>> Tony
>>>
>> --
>> SG20 mailing list
>> SG20_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/sg20
>>
> --
> SG20 mailing list
> SG20_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg20
>
Received on 2020-03-01 00:14:19