Array of const objects with indirections and std.algorithm.copy
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Wed Jul 27 11:13:52 PDT 2016
On 07/27/2016 04:51 AM, drug wrote:
> I have the following:
>
> ```
> struct Foo
> {
> int[] i;
>
> this(int[] i)
> {
> this.i = i.dup;
> }
>
> ref Foo opAssign(ref const(this) other)
> {
> i = other.i.dup;
>
> return this;
> }
> }
You're defining the assignment from const to non-const. It could have
relied on .dup or something else. The compiler cannot know the
equivalent for the copy operation.
> const(Foo)[] cfoo;
> ```
>
> I need to copy it:
>
> ```
> Foo[] foo;
>
> cfoo.copy(foo); // fails to compile because phobos in case of array uses
> // array specialization and this specialization fails
> // see
That makes sense to me. Otherwise we wouldn't be observing const-ness of
the elements: Mutate the original through the copy...
>
https://github.com/dlang/phobos/blob/v2.071.1/std/algorithm/mutation.d#L333
> ```
>
> but it works:
> ```
> foreach(ref src, ref dest; lockstep(cfoo, foo))
> dest = src;
Because the programmer said it's safe to do so. :)
> // return true
> pragma(msg, __traits(compiles, { typeof(foo).init[] =
> typeof(cfoo).init[]; } ))
(Unrelated, I've just learned that pragma() does not require a
semicolon. Ok... :) )
Well, that's interesting. I guess it means null = null, which does not
compile. I think it's a bug that the above produces true.
However, I would write that __traits(compiles) in a more straightforward
way. (You're creating a lambda there, which does not have anything to do
with the core of the problem here.) So, the following produces false, false:
pragma(msg, __traits(compiles, [ typeof(foo)() ] = [ typeof(cfoo)()
]));
pragma(msg, __traits(compiles, foo = cfoo));
Yeah, those look more straightforward to me at least for this problem.
Ali
More information about the Digitalmars-d-learn
mailing list