Thread overview
mutable reference to const object
Mar 06, 2014
Vadim Lopatin
Mar 06, 2014
FreeSlave
Mar 06, 2014
Vadim Lopatin
Mar 06, 2014
bearophile
Mar 06, 2014
Vadim Lopatin
Mar 06, 2014
bearophile
Mar 06, 2014
Vadim Lopatin
Mar 06, 2014
FreeSlave
March 06, 2014
Hello,

Is there a possibility to define mutable reference to const object?
I need variable which can be used to iterate through const objects.
But it seems like const(Foo)p makes constant reference to constant object instead of mutable reference to const object.

class Bar {
}
unittest {
   Bar bar1 = new Bar();
   Bar bar2 = new Bar();
   const(Foo) constref = bar1; // ok
   constref = bar2; // error - cannot modify const expression
}


In C++, following code works as I'm expecting:

class Bar {
}

Bar * ptr1 = new Bar();
Bar * ptr2 = new Bar();
const Bar * constptr = ptr1;
constptr = ptr2;
March 06, 2014
You probably need Rebindable template from std.typecons.
March 06, 2014
Vadim Lopatin:

> In C++, following code works as I'm expecting:

Different language, different (hopefully better) semantics. In D const and immutable are transitive, this means they make const/immutable the whole sub-tree of data they refer to:
http://dlang.org/const3.html

Bye,
bearophile
March 06, 2014
On Thursday, 6 March 2014 at 15:59:12 UTC, bearophile wrote:
> Vadim Lopatin:
>
>> In C++, following code works as I'm expecting:
>
> Different language, different (hopefully better) semantics. In D const and immutable are transitive, this means they make const/immutable the whole sub-tree of data they refer to:
> http://dlang.org/const3.html
>
> Bye,
> bearophile

Const sub-tree is object itself and its data.
Reference to object is outside of tree.
Why references to const object should be const?
Such references cannot be used to modify object anyway.
March 06, 2014
Vadim Lopatin:

> Const sub-tree is object itself and its data.
> Reference to object is outside of tree.
> Why references to const object should be const?

There was a very long discussion on this. I think the short answer is to keep the syntax and semantics composed of a sufficiently low number of parts (in D you don't have syntax to tell apart objects from their references).

A D user wrote a patch to implement what you ask for, but it was essentially left to die in GitHub.

But there's Rebindable in Phobos.

Bye,
bearophile
March 06, 2014
On Thursday, 6 March 2014 at 15:54:13 UTC, FreeSlave wrote:
> You probably need Rebindable template from std.typecons.

Thank you! Rebindable does exactly what I need.

I'm just curious why there is no some syntax to describe the same.
E.g.
   const(Foo) foo; // mutable ref to const object
   const Foo foo;  // const ref to const object

Using of const is inconvenient w/o mutable refs.
I understand that Rebindable doesn't add overhead, but it looks a bit ugly.
March 06, 2014
On Thursday, 6 March 2014 at 17:47:34 UTC, bearophile wrote:
> There was a very long discussion on this. I think the short answer is to keep the syntax and semantics composed of a sufficiently low number of parts (in D you don't have syntax to tell apart objects from their references).

Thank you!
Now it's clear.
March 06, 2014
Yes, in some cases C++ const does not provide const-guarantees, it's more like convention.

For example, you can write this:

class Class
{
public:
    Class() : ptr(new int()) {}
    ~Class() { delete ptr; }
    void setData(int data) const {
        *ptr = data;
    }
private:
    int *ptr;
};

There is interesting feature here. You can create instances that are const by its structure, but not by data. So const-method can not change size of array (reallocate), but may change data. It may be useful, for example, if you want to allow to change data in graph or another data structure, but want to disallow to add/remove vertices. Though it surely needs other definition instead of const.