insertInPlace differences between compilers
    Jesse Phillips via Digitalmars-d-learn 
    digitalmars-d-learn at puremagic.com
       
    Tue Nov 11 16:31:30 PST 2014
    
    
  
On Tuesday, 11 November 2014 at 20:53:51 UTC, John McFarlane 
wrote:
> I'm trying to write a struct template that uses 
> `insertInPlace`. However, it doesn't work with certain template 
> type / compiler combinations. Consider the following:
>
>     import std.range;
>     struct S { const int c; }
>     S[] a;
>     insertInPlace(a, 0, S());
>
> With DMD64 D Compiler v2.066.1, I get the following error:
> /usr/include/dmd/phobos/std/array.d(1013): Error: cannot modify 
> struct dest[i] S with immutable members
> /usr/include/dmd/phobos/std/array.d(1079): Error: template 
> instance std.array.copyBackwards!(S) error instantiating
> ./d/my_source_file.d(12345):        instantiated from here: 
> insertInPlace!(S, S)
I believe DMD is correct here and here is why:
While the function is called "insert" the operation is actually 
an assignment. DMD initializes all arrays elements to the default 
value so your array position 0 actually contains an S already. 
This means the operation is equivalent to
     auto b = S();
     b = S();
Since S is a value type you're actually making a modification 'c' 
as stored in 'b'. The compiler is unable to prove that there is 
no other reference to that same memory location (though in this 
case the variable is on the stack and the modification is local 
so such knowledge may be possible).
> In the short term, could anybody suggest a `static if` 
> expression to determine whether I can copy the type to the 
> satisfaction of `copyBackwards`? I tried isMutable but that 
> didn't seem to work.
>
> Thanks, John
You probably want std.traits.isAssignable
     pragma(msg, isAssignable!(S, S)); // False
    
    
More information about the Digitalmars-d-learn
mailing list