Compile-time variables

nkm1 t4nk074 at openmailbox.org
Fri Apr 6 13:55:55 UTC 2018


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.


More information about the Digitalmars-d-learn mailing list