3

我有以下结构:

template<typename tag_type>
struct tag{
    typedef tag_type type;
    enum { value = -1 }
};

我使用这个类作为 typeid 来在运行时识别特定的类。这些类中的每一个都需要在类型列表中列出,并且每个标记特化需要具有不同的值。

有没有办法使value列表中的专业化索引相等。

我的目标是使维护tag具有唯一值的专业列表尽可能容易...(我需要确保列表中的每种类型都具有唯一值,否则系统的一部分会崩溃)

编辑:我没有提到我在编译时使用这些值......

4

3 回答 3

2

我认为您的意思的非 C++11 实现,尽管您并没有真正指定类型列表的结构。

template <typename H, typename T>
struct typelist {
    typedef H head;
    typedef T tail;
};

template <typename T, typename List, int N>
struct typelist_index_i
{
    typedef typename List::tail tail;
    enum {
        value = N + typelist_index_i<T, tail, N + 1>::value
    };
};

template <typename List, int N>
struct typelist_index_i<typename List::tail, List, N>
{
    enum {
        value = N + 1
    };
};
template <typename List, int N>
struct typelist_index_i<typename List::head, List, N>
{
    enum {
        value = N
    };
};

template <typename T, typename List>
struct typelist_index
{
    enum {
        value = typelist_index_i<T, List, 0>::value
    };
};

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

typedef typelist<A, typelist<B, C> > the_types;

template<typename tag_type>
struct tag{
    typedef tag_type type;
    enum { value = typelist_index<tag_type, the_types>::value };
};

int main()
{
    std::cout << tag<A>::value << std::endl; // 0
    std::cout << tag<B>::value << std::endl; // 1
    std::cout << tag<C>::value << std::endl; // 2

    system("pause");
    return 0;
}
于 2013-07-25T13:49:38.993 回答
0

如果您不介意值在运行时之前不可用,您可以利用为全局对象调用构造函数来为您注册类。也许是这样的:

template<typename tag_type>
struct tag {
    typedef tag_type type;
    int value;
    // other info can go here, like a string representation of the class name

    tag(void) {
        register_class(this);
    }
};

#define ADD_CLASS(tag_type) tag<tag_type> __g_tag_ ## tag_type

extern int __g_class_counter;

template<typename tag_type>
static inline void register_class(tag<tag_type> *ptag) {
    ptag->value = __g_class_counter++;
    // TODO: anything else
}

// in some CPP file
int __g_class_counter = 0;

然后,您可以ADD_CLASS在需要向列表中添加类时使用宏(您可能需要移动__g_class_counter到其他位置并对其进行extern声明)。

于 2013-07-25T13:31:37.690 回答
0

这是在做你想做的事吗?它使用 C++11 特性,即可变参数模板。该index_of结构返回类型列表中类型的索引,如果类型列表不包含给定类型,则返回 -1。它是一个在 type_list 类中使用的辅助结构。type_list 类获取类列表并提供子类模板tag,该模板通过使用类模板提供对列表中各个类型的索引的访问index_of

template <int, class...>
struct index_of;

template <int n, class type, class first, class ... types>
struct index_of<n, type, first, types...>
{
        static constexpr int value = index_of<n+1, type, types...>::value;
};

template <int n, class type, class ... types>
struct index_of<n, type, type, types...>
{
        static constexpr int value = n;
};

template <int n, class type>
struct index_of<n, type>
{
        static constexpr int value = -1;
};

template <class ... types>
struct type_list
{
        template <class type>
        struct tag
        {
            static constexpr int value = index_of<0, type, types...>::value;
        };
};

用法:

using my_list = type_list<int, float, double>;
std::cout << "Tag of int: " << my_list::tag<int>::value << std::endl;
于 2013-07-25T13:40:19.980 回答