Bartosz Milewski seems to like D more than C++ now :)

Jonathan M Davis jmdavisProg at gmx.com
Fri Sep 20 11:04:10 PDT 2013


On Friday, September 20, 2013 19:02:22 Szymon Gatner wrote:
> On Friday, 20 September 2013 at 16:57:43 UTC, Jonathan M Davis
> 
> wrote:
> > If an object is const, then all of its members are const, which
> > means that any
> > ranges you get from its members will be const, making such
> > ranges useless.
> 
> That is so weird to hear considering I added ranges to my C++
> code and my Vector<T>::all() const can easily return non-const
> range even tho container is itself const. This kinda looks like D
> is more limited in that area than C++... Or I really am not
> getting something.

The container isn't the problem. It's converting a const range to a tail-const 
one (e.g. const(Range!int) to Range!(const int).

In D, const is transitive, whereas in C++, const only affects the top level. 
So, if you have

class C
{
    auto foo() const { return i; }
    private int* i;
}

then foo is going to return a const(int*). Thanks to the fact that const int* 
is implicitly convertible to const(int)*, you could also return const(int)*, 
if you chose, but you could never return int*, whereas C++ would let you do 
that just fine, because in C++ it's only the member variable itself which is 
considered const, not the whole thing, whereas in D, once an object is const, 
it and everything it refers to is const when accessed through it.

So, in D, if you have a member function that returns a range, the only way 
that it can return a non-const range is if it's able to convert the fully 
const range to a tail-const one (i.e. the range itself is non-const but what 
it refers to is still const). That can easily be done by creating an entirely 
new range from the original (e.g. convert it to an array and return that), but 
converting a const range to a tail-const one is very difficult to do with user-
defined types.

To do that, we need to be able to convert const(Range!Foo) to Range!(const 
Foo), and thanks to how templates work those are completely different template 
instantations (meaning that technically, they don't necessarily have anything 
do with each other - e.g. their internal layout could be completely different), 
so the compiler can't assume that that conversion will work. You have to write 
it yourself, which quickly runs into problems with recursive template 
instantiations and the like. I believe that it can be done with the proper use 
of static if, but it does mean that you have to know what you're doing. It's 
not straightforward, and the last time that I attempted it, I failed.

This is in stark contrast to arrays, where the compiler knows fulwell that it 
can convert const(int[]) to const(int)[] without causing any problems.

- Jonathan M Davis


More information about the Digitalmars-d mailing list