Date: Sun, 1 Mar 2020 10:20:18 +0200
I don't see why it should be different than the question when an
unconstrained template function is preferred over the non-templated one.
On Sun, Mar 1, 2020, 8:11 AM Amir Kirsh <kirshamir_at_[hidden]> wrote:
> 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
>>
>
unconstrained template function is preferred over the non-templated one.
On Sun, Mar 1, 2020, 8:11 AM Amir Kirsh <kirshamir_at_[hidden]> wrote:
> 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
>>
>
Received on 2020-03-01 02:23:15