为类型集合生成标识符

时间:2014-05-20 22:41:02

标签: c++ templates

假设我有一系列类型ABC,....

这些类型只用于标签调度,所以我希望它们是空的/无状态和最小的(空体):

struct A {};
struct B {};
struct C {};

我需要的是为每种类型创建一个唯一ID。此ID也必须是编译时常量。

我对此的第一次尝试非常typically,有一个专门针对每种类型的结构,static const成员持有ID的值:

template <typename T>
struct getID;

template <>
struct getID<A>
{
    static const int ID = 1;
};

template <>
struct getID<B>
{
    static const int ID = 2;
};

template <>
struct getID<C>
{
    static const int ID = 3;
};

template<typename T>
void testID(T val)
{
    cout << getID<T>::ID << endl;
}

int main()
{
    testID(A{});
    testID(B{});
    testID(C{});

    return 0;
}
  1. 是否有更简洁的实施?
  2. 我认为这是一个糟糕的设计,对于我添加到“集合”的每个新结构,必须正确更新代码的不同部分。有没有办法生成/生成这个结构 - &gt; ID映射?

3 个答案:

答案 0 :(得分:2)

如果您不需要持久性ID,您可以这样做:

class A {};
class B {};
class C {};

int getNextID()
{
   static int nextID = 0;
   return ++nextID;
}

template <typename T> struct GetID
{
   static int id()
   {
      static int id = getNextID();
      return id;
   }
};

int main()
{
   cout << GetID<A>::id() << endl;
   cout << GetID<B>::id() << endl;
   cout << GetID<C>::id() << endl;
   cout << GetID<int>::id() << endl;
   cout << GetID<C>::id() << endl;
};

运行上述程序的输出:

1
2
3
4
3

答案 1 :(得分:1)

创建types<Ts...>列表。 typedef一个中心实例,按顺序列出您的类型。在所述列表中使用index作为唯一id,它可以在编译时(或者在某些情况下,运行时)与类型双向关联。

作为替代方案,滥用__LINE__并在一个文件中使用宏。

template<class...>struct types{typedef types type;};
template<class T, class types>struct index_of_type;
template<class T, class... Ts>
struct index_of_type<T, types<T, Ts...>>:
  std::integral_constant< unsigned, 0 >
{};
template<class T, class T0, class... Ts>
struct index_of_type<T, types<T0, Ts...>>:
  std::integral_constant< unsigned, type_index<T, types<Ts...>>::value+1 >
{};
template<unsigned N, class types>struct type_at_index;
template<unsigned N, class T0, class... Ts>
struct type_at_index<N, types<T0, Ts...>>:type_at_index<N-1, types<Ts...>> {};
template<class T0, class... Ts>
struct type_at_index<0, types<T0, Ts...>> {
  typedef T0 type;
};
template<unsigned N, class types>
using type_at_index_t = typename type_at_index<N,types>::type;

答案 2 :(得分:1)

如果我是对的,你可以使用它:

#define STRINGIFY(x) STRINGIFY2(x)
#define STRINGIFY2(x) #x
#define GET_ID ((int)(STRINGIFY(__FILE__)":"STRINGIFY(__LINE__)))

请注意,同一文件中同一行上的此宏的两个实例可能会生成相同的数字。