Compile-type array of classes?
Tobias Pankrath
tobias at pankrath.net
Sun Feb 23 14:23:23 PST 2014
On Sunday, 23 February 2014 at 22:14:17 UTC, Gordon wrote:
> On Sunday, 23 February 2014 at 20:52:58 UTC, anonymous wrote:
>> On Sunday, 23 February 2014 at 20:34:07 UTC, Gordon wrote:
>>>
>>> Given one interface, and multiple implementation classes, I
>>> want to create a list of the classes (in compile time).
>>
>> import std.typetuple: TypeTuple;
>> alias available_animals = TypeTuple!(Dog, Cat);
>
> First, Thanks!
> D is amazing :)
>
> Now, this lead me to a weird error.
> This is the complete (contrived) program:
> ===
> import std.stdio,
> std.string,
> std.typetuple;
>
> interface Animal
> {
> static const string name() @property;
> void make_noise();
> }
>
> class Dog : Animal
> {
> static const string name() @property { return "dog" ; }
> void make_noise() { writeln("woof"); }
> }
>
> class Cat : Animal
> {
> static const string name() @property { return "cat" ; }
> void make_noise() { writeln("meow"); }
> }
>
> alias available_animals = TypeTuple!(Dog, Cat);
>
> void main()
> {
> string input_from_user = "dog";
> Animal a;
> foreach (i; available_animals) {
> if (i.name == input_from_user)
> a = new i;
> }
>
> //// -- This doesn't compile ---
> //// writeln("The ", a.name, " makes: ");
> ////
>
> a.make_noise();
> }
> ===
>
> Running the program without the marked "writeln" works fine, as
> expected.
>
> Compiling with the marked writeln, produces an "underfined
> reference" error:
> ====
> $ rdmd animals.d
> /tmp/.rdmd-34574/rdmd-animals.d-796CFD5A46BFE9DF13BF873F65EA656C/objs/animals.o:
> In function `_Dmain':
> animals.d:(.text._Dmain+0xdf): undefined reference to
> `_D7animals6Animal4nameFNdZAya'
> collect2: error: ld returned 1 exit status
> --- errorlevel 1
> ====
>
> BTW - a work-around is simple, my question is about the theory
> behind this.
>
> I understand that "Animal::name" is undefined (since "Animal"
> is an interface).
>
> but if during runtime "a" has an actual type, why does the
> compiler looks for "Animal::name" instead of Dog::Name or
> Cat::Name (based on the type of "a") ?
static methods are statically dispatched. Since they can called
without an instance, they cannot be dispatched dynamically in
general.
> It is likely because of the "static", but if I remove the
> "static" than the 'foreach' loop won't compile, because "name"
> is not static.
Correct.
> So this seems like some impossible situation...
A non static method that forwards to the static one or comparison
of the user input to the class names come to mind. Or use some
instance of i to call (the non-static) method name.
More information about the Digitalmars-d-learn
mailing list