building and accessing a list of types at compile time

旧街凉风 提交于 2019-11-26 06:41:58

问题


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.


回答1:


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;
}



回答2:


template <typename ... Types>
void info(TypeList<Types...>) {

  std::initializer_list<std::string> ls { typeid(Types).name() ... };

  for (auto& name : ls)
    std::cout << name << std::endl;
}

int main() {
  info(TYPE_LIST());
  return 0;
}


来源:https://stackoverflow.com/questions/18701798/building-and-accessing-a-list-of-types-at-compile-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!