C++ Logo

sg20

Advanced search

Re: [SG20] Difficulties in teaching the use of C++20 concepts

From: Tony V E <tvaneerd_at_[hidden]>
Date: Wed, 18 Dec 2019 00:09:54 -0500
On Tue, Dec 17, 2019 at 8:53 PM Jon Kalb <jon_at_[hidden]> wrote:

>
>
> I am/was a AAA skeptic as well, and have been waiting for Concept x = ...
> (or now Concept auto x = ...) as the sweet-spot solution.
>
> Now that we have:
>
> auto x = expr;
> Concept auto x = expr;
>
> doesn't
> int x = expr;
>
> fit the "pattern" better than
>
> auto x = int{expr};
>
>
> I think not. If I see this code:
>
> int x = expr;
>
> I’m not certain which of these is the author’s intent:
>
> - No matter what expr evaluates to, I want x to be an int.
> - This is legacy code from before auto existed.
>
> That may be true, but does it change its intent? "This is legacy code..."
is not an option for "was this the author's intent". Is there 3 choices in
this list or 2?

>
> - I’m guessing that expr returns an int ...
>
>
OK, maybe.

>
> - ... and I’m not using auto out of programming style momentum.
>
> Does that change the meaning, beyond the other points mentioned? Or is
this part redundant?



> But if I see this:
>
> auto x{int{expr}};
>
> I’m pretty certain that the meaning is, "No matter what expr evaluates to,
> I want x to be an int."
>

To be clear, you are suggesting that the "I'm guessing it returns an int"
case would just be auto x = expr; yes?
Or would some people still write the int{expr} because they (sometimes)
want to be clear about the type info? ie "I want the reader to know this is
an int, since it wasn't actually very clear in context, and it is important
in this particular case"

And, importantly, when the type of expr changes,are you sure that you still
want it to be an int, with that conversion?
Now, int doesn't have explicit constructors so it is a bad example, but
things like shared_ptr and chrono types do.
If you always write auto x = type{expr}, you lose the explicit/implicit
distinction, thus losing a safety net that the committee thought was worth
spending a keyword on. In fact, most guidelines suggest explicit should be
the default choice for constructors, yet this form of auto works against
that guideline.


> What is the value of
>
> auto x = int{expr};
>
>
> This better conveys the intention that you really want x to be int without
> regard to the type of expr. The alternative “int x = expr;” just invites
> someone to notice that expr (either now or the future) might not be an int,
> and thus reflector it as “auto x{expr};
>

What about when I want it to be int regardless of the type of expr, unless
that is an explicit conversion, because in that case I probably want to
double-check.

Or what if I write auto x = type{expr} *precisely* because I want the
explicit conversion?
Does that mean whenever I see auto x = type{expr} I'm left wondering "do
they want the explicit conversion, or is this just their style for all
occassions?"


You didn't comment on the examples which motivate my concerns:

Two real-life examples, from Howard Hinnant, paraphrased:
>
> auto ns = nanoseconds{duration}; // duration was a chrono type, but
> became int, is this still what you wanted???
> vs
> nanoseconds ns = duration; // if duration is strong chrono type, does the
> conversion you wanted/expected, if duration is int, fails to compile
>
> And
>
> auto sp = shared_ptr<Foo>(ptr); // ptr is a weak_ptr, need shared
> vs
> shared_ptr<Foo> sp = ptr;
>
> When, under maintenance, ptr changes from weak_ptr to raw T* ptr, one of
> those lines is probably a bug, the other doesn't compile.
> (And yes, maybe they should have called ptr.lock() on the weak ptr, but
> some people think that was a poorly named function (confusing with mutex
> etc) and prefer the conversion style.)
>
>
> So I still prefer int x = expr; over auto x = int{expr};, and I think int
> x = expr nicely follows a pattern with auto x = expr and Concept auto x =
> expr.
>
>
> --
Be seeing you,
Tony

Received on 2019-12-17 23:12:32