Rainer Deyke wrote:
Andrei Alexandrescu wrote:
Well I never seemed to have a problem with it, quite the contrary in
fact. Values are easier to reason about because they don't have aliasing
and don't foster long-distance interdependencies.

This.

When the container is used in a struct, then it must not only be copied,
but deep-copied when the outer struct is copied.  The same applies when
the container is used in a class that has a cloning operation defined.

When the container is used in a class that cannot be cloned or is
directly placed on the stack, then it doesn't really matter if the
container has reference or value semantics, since the variable that
holds the container isn't being copied anyway.

For those very rare cases where you /want/ the container to be shared,
you can always use a pointer to the container.

Spot on. My ambitions are actually a tad higher. I want to implement containers as by-value structs defining value semantics and the needed primitives. Then, using introspection, I want to define a template Class that takes a struct and turns it into a class. For example:

struct SomeContainer(T)
{
    ref T opIndex(size_t n) { ... }
}

auto byval = SomeContainer!(int)();
auto javalike = new Class!(SomeContainer!(int));

The type Class!(SomeContainer!(int)) will store a SomeContainer!(int) object and will define (by using introspection) a method opIndex of which implementation will do what the struct's method does. The net effect is as if the programmer sat down with SomeContainer and changed "struct" to "class". Of course without the code duplication and the maintenance nightmare :o).

Class should work for primitive types, e.g. Class!(int) should do what Integer does in Java and so on.


Andrei

Reply via email to