Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile-time template `std::integral_constant` counter - how to implement it?

I have several types and I want to "bind" an std::integral_constant sequential ID value to every type at compile-time.

Example:

struct Type00 { };
struct Type01 { };
struct Type02 { };
struct Type03 { };
struct TypeXX { };
struct TypeYY { };

template<typename T> struct TypeInfo
{
    using Id = std::integral_constant<int, ???>;
};

int main()
{
     cout << TypeInfo<Type00>::Id::value; // Should always print 0
     cout << TypeInfo<Type01>::Id::value; // Should always print 1
     cout << TypeInfo<Type02>::Id::value; // Should always print 2
     cout << TypeInfo<Type03>::Id::value; // Should always print 3
     cout << TypeInfo<TypeXX>::Id::value; // Should always print 4
     cout << TypeInfo<TypeYY>::Id::value; // Should always print 5
}

The problem is that I don't know how to keep track of the last used ID. Ideally, I want something like:

template<typename T> struct TypeInfo
{
    using Id = std::integral_constant<int, lastUsedID + 1>;
};

Is there any way to define and keep track of a compile-time lastUsedID?

How can I solve this problem?


EDIT:

Clarifications:

  • TypeInfo<...> needs to be frequently called in user code. The syntax must remain clear (the user doesn't (need to know there's a) / (manually increment the) compile-time counter)
  • Typeinfo<T>::Id::value must always return the same value in the whole program. The initial value will be "bound" on the first instantiation, to lastUsedID + 1.
  • I can use all C++11 and C++14 features.
  • Listing all types before calling TypeInfo<...> is not a proper solution.
like image 880
Vittorio Romeo Avatar asked Sep 18 '14 15:09

Vittorio Romeo


1 Answers

It is not possible and it's quite easy to see why: Consider two compilation units. Unit one sees type Type00, but not Type01, while unit two sees Type01 but not Type00. There is nothing in C++ (including C++11 and C++14) which could now tell the compiler in both compilation units which order those types should have. Even adding some data to the object file for link-time is too late, as you are asking for a compile-time value. This is the fundamental concept of compilation units which poses a hard barrier for the feature you are asking for.

like image 53
Daniel Frey Avatar answered Oct 02 '22 18:10

Daniel Frey