在编译时构建和访问类型列表 [英] building and accessing a list of types at compile time

查看:81
本文介绍了在编译时构建和访问类型列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用c ++模板元编程实现以下。我希望构建一个类型列表,然后一起收集这些类型,并在列表上做进一步的编译时处理。例如:



foo.h:

  class Foo { ...}; 
//插入任何代码

bar.h:

  class Bar {...}; 
//插入任何代码

main.h:

  #includefoo.h
#includebar.h

struct list_of_types {
typedef / * INSERT ANY CODE HERE * / type;
};

我可以将任何代码插入上面的插槽,只要list_of_types :: type解析为某种表示(例如boost :: mpl :: vector)包含类型Foo和Bar的列表。以下限制适用:


  1. foo.h中的代码不应该知道bar.h中的代码,反之亦然。


  2. main.h中的代码不应该包含



解决方案

解决方案使用公共头部,可变参数模板和宏:

  //标题common.h 

/ / A distinct Void type
struct Void {};

template< typename ...> struct concat;

template< template< typename ...>类List,类型名T>
struct concat< List< Void>,T>
{
typedef List< T>类型;
};

template< template< typename ...> class List,typename ... Types,typename T>
struct concat< List< Types ...>,T>
{
typedef List< Types ...,T>类型;
};

template< typename ...> struct TypeList {};

模板<>
struct TypeList< Void> {};
typedef TypeList< Void> TypelistVoid;
#define TYPE_LIST TypelistVoid


//标题foo.h
// #include< common.h>

class Foo {};

typedef typename concat< TYPE_LIST,Foo> :: type TypeListFoo;
#undef TYPE_LIST
#define TYPE_LIST TypeListFoo


// Header bar.h
// #include< common.h>

class Bar {};

typedef typename concat< TYPE_LIST,Bar> :: type TypeListBar;
#undef TYPE_LIST
#define TYPE_LIST TypeListBar



//头文件main.h
// #includefoo.h
// #includebar.h

struct list_of_types {
typedef TYPE_LIST type;
};
//或只是typedef TYPE_LIST list_of_types;

//测试
#include< iostream>
#include< typeinfo>

template< template< typename ...> class List,typename T,typename ... Types>
void info();

template< typename T,typename ... Types>
inline void info(TypeList< T,Types ...>){
std :: cout< typeid(T).name()<< std :: endl;
info(TypeList< Types ...>());
}

template< typename T>
inline void info(TypeList< T>){
std :: cout< typeid(T).name()<< std :: endl;
}

int main(){
info(list_of_types :: type());
return 0;
}


I am trying to achieve the following using c++ template metaprogramming. I wish to build up a list of types and then collect these types together and do further compile-time processing on the list. So for example:

foo.h:

class Foo { ... };
// INSERT ANY CODE HERE

bar.h:

class Bar { ... };
// INSERT ANY CODE HERE

main.h:

#include "foo.h"
#include "bar.h"

struct list_of_types {
  typedef /* INSERT ANY CODE HERE */ type;
};

I can insert any code into the slots above, so long as list_of_types::type resolves to some representation (e.g. a boost::mpl::vector) of a list containing the types Foo and Bar. The following restrictions apply:

  1. The code in foo.h should not know about the code in bar.h, and vice versa. It should be possible to change the order of #include directives in main.h and not change any other code.

  2. The code in main.h should not have to change if I include further headers that add further types to the list.

  3. The list of types must be available at compile time. I am planning to do further metaprogramming involving the list.

解决方案

A solution utilizing a common header, variadic templates and a macro:

// Header common.h

// A distinct Void type
struct Void {};

template <typename ...> struct concat;

template <template <typename ...> class List, typename T>
struct concat<List<Void>, T>
{
    typedef List<T> type;
};

template <template <typename ...> class List, typename ...Types, typename T>
struct concat<List<Types...>, T>
{
    typedef List<Types..., T> type;
};

template <typename...> struct TypeList {};

template <>
struct TypeList<Void> {};
typedef TypeList<Void> TypelistVoid;
#define TYPE_LIST TypelistVoid


// Header foo.h
// #include <common.h>

class Foo { };

typedef typename concat<TYPE_LIST, Foo>::type TypeListFoo;
#undef TYPE_LIST
#define TYPE_LIST TypeListFoo


// Header bar.h
// #include <common.h>

class Bar { };

typedef typename concat<TYPE_LIST, Bar>::type TypeListBar;
#undef TYPE_LIST
#define TYPE_LIST TypeListBar



// Header main.h 
// #include "foo.h"
// #include "bar.h"

struct list_of_types {
    typedef TYPE_LIST type;
};
// Or just typedef TYPE_LIST list_of_types;

// Test
#include <iostream>
#include <typeinfo>

template <template <typename ...> class List, typename T, typename ...Types>
void info();

template <typename T, typename ...Types>
inline void info(TypeList<T, Types...>) {
    std::cout << typeid(T).name() << std::endl;
    info(TypeList<Types...>());
}

template <typename T>
inline void info(TypeList<T>) {
    std::cout << typeid(T).name() << std::endl;
}

int main() {
    info(list_of_types::type());
    return 0;
}

这篇关于在编译时构建和访问类型列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆