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.






Reply via email to