On Friday, 6 April 2018 at 13:55:55 UTC, nkm1 wrote:
On Friday, 6 April 2018 at 13:10:23 UTC, Kayomn wrote:
ID tags are unique and spsecific to the class type. There shouldn't be more than one type ID assigned to one class type.

The idea behind what it is I am doing is I am implementing a solution to getting a type index, similar to std.variant.Variant.type(). The way that I implemented this in C++ is like so:

--------------------------------------------------------------------------------
inline unsigned int getNodeTypeID() {
    static unsigned int lastID = 0;

    return lastID++;
}

template<typename T> inline unsigned int getNodeTypeID() {
    static unsigned int typeID = getNodeTypeID();

    return typeID;
}
--------------------------------------------------------------------------------

In this C++ example I am exploiting the fact that templates are generated at compile-time to execute getNodeTypeID for each new type instance generated. After initial type generation, whenever they are called at runtime they were return the ID assigned to that function template instance that was generated at compile-time.

It's pretty simple, and to be honest I'm surprised this has been causing me such a headache implementing it in D.

That's because the C++ code doesn't do what you think it does. Apparently you think that getNodeID() is executed at compile time. This is not the case, which you can verify by adding "constexpr" to it:

$ g++ -std=c++14 -Wall -Wextra -c -o example example.cpp
main.cpp: In function ‘constexpr unsigned int getNodeTypeID()’:
main.cpp:2:25: error: ‘lastID’ declared ‘static’ in ‘constexpr’ function
     static unsigned int lastID = 0;

In fact, you're "exploiting" the fact that static variables in C++ can be initialized at runtime (which is probably not what you want).
The equivalent D code is:

uint newID()
{
    static uint lastID;

    return lastID++;
}

uint getNodeID(T)()
{
    static bool inited;
    static uint id;

    if (!inited)
    {
        id = newID();
        inited = true;
    }

    return id;
}

(yes, C++ does insert some hidden bool that tells it whether the variable was initialized or not). Naturally, you can't use that for constructing switches or other compile time constructs.

Figured I had a handle on how it worked doing but guess not. One final question, however.

I've implemented this test bed with your example to what I think is your exact implementation, but it seems to be giving unexpected output.

--------------------------------------------------------------------------------
import std.stdio;

uint newID() {
        static uint lastID;

        return lastID;
}

uint getNodeID(T)() {
        static bool inited;
        static uint id;

        if (!inited) {
                id = newID();
                inited = true;
        }
        return id;
}

class Node {}

class Sprite {}

class Camera {}

void main() {
        // Test 01.
        writeln("Test 01.");
        
writeln(getNodeID!(Node)(),'\t',getNodeID!(Sprite)(),'\t',getNodeID!(Camera)());
        // Test 02.
        writeln("Test 02.");
        
writeln(getNodeID!(Node)(),'\t',getNodeID!(Sprite)(),'\t',getNodeID!(Camera)());
}
--------------------------------------------------------------------------------

Output:
--------------------------------------------------------------------------------
Performing "debug" build using gdc for x86_64.
dlangtest ~master: building configuration "application"...
Running ./dlangtest
Test 01.
0       0       0
Test 02.
0       0       0
--------------------------------------------------------------------------------

Have I misunderstood something?

Reply via email to