簡體   English   中英

C ++在類型列表中創建模板特化

[英]C++ creating template specialisation in a typelist

我有以下結構:

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

我使用此類作為typeid來在運行時標識特定的類。 這些類中的每一個都需要列在類型列表中,並且每個標記特化需要具有不同的值。

有沒有辦法使value等於列表中的特化指數。

我的目標是盡可能簡單地維護具有唯一值的專用tag列表...(我需要確保列表中的每個類型都具有唯一值或系統的一部分將崩潰)

編輯:我沒有提到我在編譯時使用值...

我認為你的意思的非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;
}

如果您不介意在運行時之前不可用的值,則可以使用為全局對象調用的構造函數來為您注冊類。 也許是這樣的:

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聲明)。

這樣做你想要的嗎? 它使用C ++ 11功能,即可變參數模板。 index_of結構返回類型列表中類型的索引,如果類型列表不包含給定類型,則返回-1。 它是一個在type_list類中使用的輔助結構。 type_list類獲取類列表並提供子類模板tag ,該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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM