Array of templated classes or structs

TheFlyingFiddle via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Oct 24 11:29:07 PDT 2015


On Saturday, 24 October 2015 at 15:57:09 UTC, Dandyvica wrote:
> Hi guys,
>
> Apart from deriving from the same class and declaring an array 
> of that
> root class, is there a way to create an array of templates?
>
> This seems not possible since template are compile-time 
> generated, but just to be sure. For example, it seems logical 
> to get an array of complex numbers but Complex needs to be 
> declared with a type.
>
> Thanks for any hint.
Structs or classes that are templated will create new types each 
time they are instantiated.

struct S(T) { /*stuff*/ }
static assert(!is(S!int == S!double));

So you can create arrays of:
S!int[] a; or
S!double[] b;

But you can't really create arrays of S!(int or double)[].

However it can be sort of done by using a variant(taged union).

import std.variant;
alias SIntOrDouble = Algebraic!(S!int, S!double);

SIntOrDouble[] array;
array ~= S!int(...);
array ~= S!double(...);


Now the array holds two items an S!int for the first item and an 
S!double for the second.

You can use it like this.
foreach(ref elem; array)
{
    if(auto p = elem.peek!(S!int))
    {
       //Do stuff with an S!int item
    }
    else if(auto p = elem.peek!(S!double))
    {
       //Do stuff with an S!double.
    }
}

Or like this:
foreach(ref elem; array)
{
    elem.visit!(
    (S!int i) => /*something with ints*/,
    (S!double d) => /*something with doubles*/
    );
}

Take a look at std.variant if you are interested.

A drawback to the Algebraic is that you must know all the 
different template instantiations that you will be using. If you 
don't know this I suggest you use a variant instead.

The line:
SIntOrDouble[] array;
changes to
Variant[] array;

With this you can hold anything in the array. This is both an 
advantage and a drawback, the advantage is that you can just add 
more templpate instantiations to the program as is evolves. But 
you lose static typing information so the compiler will not be 
able to help you anymore. For example this would be valid:

Variant[] array;
array ~= S!int(...);
array ~= S!double(...);
array ~= S!long(...);
array ~= "I am a string!";

And this is probably not what you want.








More information about the Digitalmars-d-learn mailing list