March 20, 2016
So this is mostly curiosity and not completely related to D but I would like to know how a vtable is actually implemented. All the explanations that I have seen so far are a bit vague and it would be nice to actually see some code.

I tried to implement the following myself

interface Something{
   void print();
   int getNumber();
}

This is how I would do it:

struct VDispatch(Types...){
    void* vptr;
    char typeId;

    void print(){
        foreach(index, type; Types){
            if(index == typeId){
                (cast(type*)vptr).print();
            }
        }
    }

    int getNumber(){
        foreach(index, type; Types){
            if(index == typeId){
                return (cast(type*)vptr).getNumber();
            }
        }
        throw new Error("Unknown Type");
    }

    this(T)(T* ptr){
        import std.meta: staticIndexOf;
        vptr = cast(void*)ptr;
        typeId = staticIndexOf!(T, Types);
    }
}


struct Foo{
    int number;
    void print(){
        import std.stdio;
        writeln("Foo: ", number);
    }
    int getNumber(){
        return number;
    }
}

struct Bar{
    int number;
    void print(){
        import std.stdio;
        writeln("Bar: ", number);
    }
    int getNumber(){
        return number;
    }
}

unittest{
    import std.stdio;
    alias VFooBar = VDispatch!(Foo, Bar);
    auto t = VFooBar(new Foo(42));
    auto t1 = VFooBar(new Bar(24));
    t.print();
    t1.print();
    writeln(t.getNumber());
    writeln(t1.getNumber());
}

Is this how it works internally? I assume the compiler would generate which types actually supported at runtime? I have modeled this as a variadic template "Types..." and it has to be managed by the user.

March 20, 2016
Read the ABI page again, its fairly sufficient about this stuff.

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus