我正在尝试使用c++模板元编程来实现以下目标。我希望建立一个类型列表,然后将这些类型收集在一起,并对列表进行进一步的编译时处理。因此,例如:

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

只要list_of_types::type解析为包含Foo和Bar类型的列表的某种表示形式(例如boost::mpl::vector),我就可以在上面的插槽中插入任何代码。适用以下限制:
  • foo.h中的代码不应该知道bar.h中的代码,反之亦然。应该可以在main.h中更改#include指令的顺序,而不更改任何其他代码。
  • 如果我包括将其他类型添加到列表的其他头文件,则不必更改main.h中的代码。
  • 类型列表必须在编译时可用。我打算进行涉及该列表的进一步元编程。
  • 最佳答案

    一种使用通用 header ,可变参数模板和宏的解决方案:

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

    关于c++ - 在编译时建立和访问类型列表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18701798/

    10-11 22:42