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