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
,该模板通过使用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;
相关文章:
- 如何使用默认参数等选择模板专业化
- 模板化建造师专业化
- 类模板的成员功能的定义在单独的TU中完全专业化
- 部分专业化和嵌套模板
- 模板专业化可以进入我的.cpp吗?
- 别名模板的专业化 C++11 中没有开销的最佳替代方案
- 部分专业化和对标准::void_t<>的需求
- 满意和建模的概念?
- "专业化不参与超载"
- 特定好友功能专业化
- 是否可以混合使用SFINAE和模板专业化?
- 为什么在班级专业化上会出现错误?
- enable_if如何帮助选择类模板的专业化?
- std::initializer_list可以专业化吗?
- 派生类中纯虚拟基方法的专业化
- "expected a '>'"类模板专业化?
- Clang不会编译GCC会编译的模板专业化
- 我可以用clang AST从模板专业化中获得默认的模板参数吗
- 函数模板部分专业化-有什么解决方法吗
- 类模板的编译错误,但其专业化除外