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") ?

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.

So this seems like some impossible situation...



Reply via email to