Date: Sun, 1 Mar 2020 09:31:14 +0100
If the concept is modeling the required operations than it can be used to make the function more generic, eg, by allowing safe integers of varying flavor. I would need to check if std::integral is an extension point, or only allows the built ins. May be requiring arithmetic type is even better, but who knows without seeing the body and applications.
Also void return is usually bad practice since it relies on side effects. Void return without non-const reference parameter or other mutable relationship type will be untestable, because it will rely on globals.
Peter
sent from a mobile device so please excuse strange words due to autocorrection.
Peter Sommerlad
peter.cpp_at_[hidden]
+41-79-432 23 32
> On 1 Mar 2020, at 07:11, Amir Kirsh via SG20 <sg20_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
> --
> SG20 mailing list
> SG20_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg20
Also void return is usually bad practice since it relies on side effects. Void return without non-const reference parameter or other mutable relationship type will be untestable, because it will rely on globals.
Peter
sent from a mobile device so please excuse strange words due to autocorrection.
Peter Sommerlad
peter.cpp_at_[hidden]
+41-79-432 23 32
> On 1 Mar 2020, at 07:11, Amir Kirsh via SG20 <sg20_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
> --
> SG20 mailing list
> SG20_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg20
Received on 2020-03-01 02:34:00