Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 27, 2015 Associative Array of Const Objects? | ||||
---|---|---|---|---|
| ||||
class Test{} void main() { const(Test)[string] tests; tests["test"] = new Test(); } This code used to work, but after upgrading to dmd 2.067, it no longer does. --Error: cannot modify const expression tests["test"] How do I insert an item into an associative array of const objects? |
March 28, 2015 Re: Associative Array of Const Objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bitwise | bitwise:
> class Test{}
>
> void main()
> {
> const(Test)[string] tests;
> tests["test"] = new Test();
> }
>
> This code used to work, but after upgrading to dmd 2.067, it no longer does.
> --Error: cannot modify const expression tests["test"]
>
> How do I insert an item into an associative array of const objects?
You meant to say "associative array with const objects as values". I think the short answer is that you can't. This is a breaking change, I think, it broke some of my code too. But perhaps something like Rebindable could be used.
Bye,
bearophile
|
March 28, 2015 Re: Associative Array of Const Objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bitwise | On Friday, 27 March 2015 at 21:33:19 UTC, bitwise wrote: > class Test{} > > void main() > { > const(Test)[string] tests; > tests["test"] = new Test(); > } > > This code used to work, but after upgrading to dmd 2.067, it no longer does. > --Error: cannot modify const expression tests["test"] > > How do I insert an item into an associative array of const objects? FWIW, it was changed in https://github.com/D-Programming-Language/dmd/pull/4148 It seems Kenji argues that the first assignment (like in your case) should be allowed, because it's supposed to be a construction rather than an assignment, but I fail to see how the compiler could detect this in the general case. |
March 28, 2015 Re: Associative Array of Const Objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bitwise | On Friday, 27 March 2015 at 21:33:19 UTC, bitwise wrote:
> class Test{}
>
> void main()
> {
> const(Test)[string] tests;
> tests["test"] = new Test();
> }
>
> This code used to work, but after upgrading to dmd 2.067, it no longer does.
> --Error: cannot modify const expression tests["test"]
>
> How do I insert an item into an associative array of const objects?
Generally speaking, you can insert an item in a constructor:
---
class Test{}
const (Test)[string] tests;
static this()
{
tests["test"] = new Test();
}
class Bar
{
immutable (Test)[string] tests2;
this()
{
this.tests2["test"] = new Test();
}
}
void main()
{
auto bar = new Bar;
}
---
The same problem already existed before 2.067 for AA with strings as value (string[string]), since they are immutable.
|
March 29, 2015 Re: Associative Array of Const Objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | I'm a little confused at this point why this doesn't work either: const(Test) test = new Test(); // fine test = new Test(); // error In C++, There is a clear distinction: const Test *test1 = nullptr; // const before type test1 = new Test(); // fine Test *const test2 = nullptr; // const before identifier test2 = new Test(); // error: test2 is readonly Isn't there such a distinction in D? I would have suggested that I got things backward, but this doesn't work either: const Test test = new Test(); test = new Test(); // error: cannot modify const expression |
March 29, 2015 Re: Associative Array of Const Objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bitwise | bitwise: > I'm a little confused at this point why this doesn't work either: const and immutable are rather different between C++ and D, I suggest you to take a look at the documentation: http://dlang.org/const-faq.html Bye, bearophile |
March 29, 2015 Re: Associative Array of Const Objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > perhaps something like Rebindable could be used.
Looking at Rebindable now, there is a useful example. There should probably be a mention of this on the const/immutable docs. For people coming from C++, this will not be obvious.
auto a = Rebindable!(const Widget)(new Widget);
a.y(); // fine
a.x = 5; // error! can't modify const a
a = new Widget; // fine
Given the above example though, I have to say it's ridiculously verbose and I much prefer the C++ way. I have never used read-only-const in C++, nor would I, and it's really annoying that it's forced on D programmers. I can see the benefit of protecting the underlaying data, but not the pointer/reference itself.
I'm assuming a DIP for this would be futile at best =/
Thanks
|
March 29, 2015 Re: Associative Array of Const Objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bitwise | On Sunday, 29 March 2015 at 18:43:32 UTC, bitwise wrote: > I'm a little confused at this point why this doesn't work either: > > const(Test) test = new Test(); // fine > test = new Test(); // error > > > In C++, There is a clear distinction: > > const Test *test1 = nullptr; // const before type > test1 = new Test(); // fine > > Test *const test2 = nullptr; // const before identifier > test2 = new Test(); // error: test2 is readonly > > Isn't there such a distinction in D? Notice how you have that '*' there that allows you to distinguish the data from the reference. You can have a mutable pointer to const data in D, too: struct Test {} const(Test)* test1 = null; test1 = new Test; /* fine */ const(Test*) test2 = null; /* equivalent variant: const Test* test2 = null; */ test2 = new Test; /* Error: cannot modify const expression test2 */ You cannot have a mutable class object reference to const data, because syntactically that distinction isn't made in D. There is std.typecons.Rebindable, though: import std.typecons: Rebindable; class Test {} Rebindable!(const Test) test = null; test = new Test; /* fine */ > I would have suggested that I got things backward, but this doesn't work either: > > const Test test = new Test(); > test = new Test(); // error: cannot modify const expression `const Test test` is the same as `const(Test) test`. |
March 29, 2015 Re: Associative Array of Const Objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | On Sunday, 29 March 2015 at 19:04:30 UTC, anonymous wrote:
>
> Notice how you have that '*' there that allows you to distinguish the data from the reference.
>
> You can have a mutable pointer to const data in D, too:
>
> struct Test {}
> const(Test)* test1 = null;
> test1 = new Test; /* fine */
> const(Test*) test2 = null;
> /* equivalent variant: const Test* test2 = null; */
> test2 = new Test; /* Error: cannot modify const expression test2 */
>
> You cannot have a mutable class object reference to const data, because syntactically that distinction isn't made in D. There is std.typecons.Rebindable, though:
>
> import std.typecons: Rebindable;
> class Test {}
> Rebindable!(const Test) test = null;
> test = new Test; /* fine */
>
>> I would have suggested that I got things backward, but this doesn't work either:
>>
>> const Test test = new Test();
>> test = new Test(); // error: cannot modify const expression
>
> `const Test test` is the same as `const(Test) test`.
Interesting, but I still don't understand why D doesn't have something like this:
const Test test; // or const(Test) test;
test = new Test() // fine, underlaying data is const, the reference is not
Test const test = new Test();
test.a = 5; // fine, test is read-only but underlaying data is not const
test = new Test(); // error: test is read-only
const(Test) const test = new Test();
test.a = 5; // error, underlaying data is const
test = new Test(); // error: read-only
|
Copyright © 1999-2021 by the D Language Foundation