copy must be const?!?
Dom DiSc
dominikus at scherkl.de
Mon Jul 29 13:13:45 UTC 2024
On Friday, 26 July 2024 at 10:04:45 UTC, Jonathan M Davis wrote:
> On Friday, July 26, 2024 2:17:21 AM MDT Dom DiSc via
> Digitalmars-d-learn wrote:
>> If you are not able to construct a mutable copy of a type, why
>> on earth are you handing it over by value?!?
>
> Why not?
Because you can't make a mutable copy?
> Structs are [...] often pseudo-reference types. [...]
> such types can often work just fine with const copies, because
> the data that's shared between objects is const or immutable.
Then declare the template to take a const parameter.
>> ```d
>> immutable MyNonCopyableType x;
>> MyNonCopyableType y = x; // compile error?
>> ```
>
> If you can't get a mutable copy of MyNonCopyableType, then yes,
> you'll get a compiler error.
This is why you should get the same error, if the compiler cannot
create a mutable parameter-by-value copy.
> In D, const is pretty much cancer, honestly. You do _not_ want
> to use it for generic code if you can possible avoid it,
Why? In a template that guarantees not to modify a parameter by
declaring it const, what bad can happen?
> because many, many types do not work with it at all.
At least reading it should never be a problem. And nothing more
one want to do with a const parameter.
But I don't see your problem. I'm taking about situations where a
const instance of a type IS ALREADY THERE (which will never be
the case with any of your problematic types), and I want to have
a mutable copy of them.
So if the compiler would discard the const from parameters that
are anyway never const, that's a NOP. All is fine.
On the other hand if there is a const object, that should be an
object of a type that indeed CAN provide mutable copies. This is
also fine.
So, where is the problem if the compiler drops "const" from the
by-value copy of a parameter?
> in situations where a type can be logically const (or which
> could be const in C++), it cannot be const in D, because D's
> const is simply too restrictive.
Sorry, but if a type is "logically const" (like a range) and you
read it and thereby change it's internal state, then the template
that guaranteed not to modify a parameter is very likely to
destroy this internal state, and so you are much better of if
this doesn't compile beforehand.
Some templates are simply not meant to work with all kinds of
user defined types.
> If you declare the parameter to be const, then there are a lot
> of types that won't work with the template.
Fine. If I can change the internal state via read-functions, I
don't want to work with that bogous type. If my intention is not
to modify an object, I'm perfectly ok that I can't use may of
that fake-const types functions.
> On top of that, in many cases, getting a mutable copy would
> give you completely incorrect behavior - e.g. if a range is a
> range over a container, you need that range to point to the
> elements in the container, and if the range refers to those
> elements as const, then getting a mutable copy of those
> elements would mean that they're no longer necessarily the same
> elements which are in the container (they might be at the point
> that the copy is made, but that won't necessarily stay true,
> whereas it would if the elements aren't copied).
Ranges are a bad example, because they really cannot be const.
They are completely unusable in a function not modifying them,
because reading them is using them up. So a function taking a
range as parameter indeed cannot guarantee not to modify it (at
least not if it reads that parameters data at all).
> It's also the case that a lot of code simply avoids using const
> altogether with user-defined types
Fine. Then you won't run into the problem I have. And indeed, as
you weren't aware of this problem is an indicator that you are
not really using const.
> Most anyone who tries to use D's const like you would in C++
> eventually stops, because D's const is simply too different
> from C++'s const for that to work.
No, so far the C++ code I converted to D is working fine. And it
is heavily using const - but it uses it correct, despite C++
doesn't enforce that. Maybe I never used C++ the way it was
meant?!?
> And that's especially true with templated code, since if it has
> to work with a large range of types, types which don't work
> with const are going to be on the list.
Nope. Constraints work very good in guaranteeing that such types
are NOT on the list of types the template is working with.
> On top of that, some common D idioms (e.g. ranges) can't work
> with const, because they require mutation (a range can have
> const elements, but the range itself cannot be const).
Jup. If a template takes a range, it should not take it const.
But I also won't take a range by value. As whatever I do will
modify the range, why should I pretend to work on a copy of it?
Take it by ref!
More information about the Digitalmars-d-learn
mailing list