Making containers that "go both ways"

Yigal Chripun yigal100 at gmail.com
Sat Jan 26 11:11:59 PST 2008


Bill Baxter wrote:
> Jarrett Billingsley wrote:
>> "janderson" <askme at me.com> wrote in message 
>> news:fnem61$2054$1 at digitalmars.com...
>>
>>> Personally I'd make it a class.  Yes its going to go on the heap 
>>> however the resizeable array part or whatever the container contains, 
>>> will probably go on the heap anyway.
>>
>> Good point.  Also keep in mind that even if it's a class, it can be 
>> allocated on the stack in functions if you use 'scope x = new X()', so 
>> there's at least one heap allocation avoided. 
> 
> And if it's a struct it can be allocated on the heap using new if you like.
> 
> I would be much more inclined to use classes for containers if they 
> either didn't require new, or could be new'ed at point of declaration 
> (like I think they can in Java?).
> 
> This scattering of information all over the place is one of the things 
> that annoys me most about C++.
> 
> // Annoying
> class D {
>     MyContainer c; // must remember to 'new' this later in constructor
>     int[] d; // no worries, it's good.
>     MyStructContainer e; // also no worries
> 
>     ...
>     this() {
>         c = new MyContainer;
>     }
> }
> 
> // This would be less annoying
> class D {
>     MyContainer c = new MyContainer;
> 
>     ...
>     this() {}
> }
> 
> // Or this
> class D {
>     scope MyContainer c;
> 
>     ...
>     this() {}
> }
> 
> And the second reason I think containers should be structs is because if 
> you want to "upgrade" some existing code from using a built-in array or 
> AA to using a custom container, it's much less headache if it's a 
> struct-based container.  Also if you want to write generic code that can 
> handle built-in and custom containers, then it's going to be easier if 
> your custom containers are structs.
> 
> I think main important difference is the way copying is handled, but 
> unfortunately "places where a container of type X is copied and 
> subsequently it is assumed that X.member is a distinct pointer" is 
> pretty difficult to grep for.
> 
> Initialization is also different but you initialize things far less 
> often than you pass them around or assign them to other variables. 
> Initialization patterns are also easier to grep for.
> 
> That's my 2c.
> 
> --bb

the way it's done in other oop languages like java, c#, etc:
there's a hierarchy of interfaces and separate implementations. so as a 
user i use for example :

List<Type> variable = new SomeImplClass();

if i have a function that iterates over a list of stuff i don't need to 
know what implementation was chosen i just rely on the interface. also 
functions should use the most general interface that suits the problem. 
so i can use a

func(container con, other params... )

in order to do similar with structs you need to use template functions 
and you don't have a way to insure that all containers have that same 
base "container" interface (isn't the new c++ standard tries to solve it 
with concepts?). also if i have different container types that creates 
overhead in the executable size (code duplication).

-- Yigal




More information about the Digitalmars-d mailing list