【问题标题】:How to transform this list of types with brigand?如何用强盗转换这个类型列表?
【发布时间】:2018-11-18 23:05:44
【问题描述】:

我有以下类型列表:

using ComponentList = brigand::list<TransformComponent, ObjectComponent, BodyComponent>

如何将以前的列表转换为如下所示的新列表:

using ComponentHandleList = brigand::list<entityx::ComponentHandle<TransformComponent>, entityx::ComponentHandle<ObjectComponent>, entityx::ComponentHandle<BodyComponent>>;

我基本上想生成一个新列表,其中包含前一个列表中每个元素的包装器。 我尝试使用:

using ComponentHandleList = brigand::transform<ComponentList, AddComponentHandle<brigand::_1>>;

但我对元编程知之甚少,未能实现struct AddComponentHandle&lt;&gt;,它将采用T 类型并将其转换为entityx::ComponentHandle&lt;T&gt;。 Brigand 包含有关转换类型列表的相关documentation,通过显示使用std::add_pointer&lt;&gt; 将每种类型T 转换为T* 的示例。这是我想做的同一件事,但从Tentityx::ComponentHandle&lt;T&gt;。如何转换第一个列表使其看起来像第二个?

【问题讨论】:

    标签: c++ c++11 templates variadic-templates template-meta-programming


    【解决方案1】:
    #include <brigand/sequences/list.hpp>
    #include <brigand/algorithms/transform.hpp>
    #include <type_traits>
    
    struct TransformComponent{};
    struct ObjectComponent{};
    struct BodyComponent{};
    namespace entityx
    {
        template <typename Component>
        struct ComponentHandle{};
    }
    
    using ComponentList = brigand::list<TransformComponent, ObjectComponent, BodyComponent>;
    
    template <typename Comp>
    using AddComponentHandle = entityx::ComponentHandle<Comp>;
    
    template <typename Comp>
    struct AddComponentHandle2
    {
        using type = entityx::ComponentHandle<Comp>;
    };
    
    using ComponentHandleList = brigand::transform<ComponentList, brigand::bind<AddComponentHandle,brigand::_1>>;
    using ComponentHandleList2 = brigand::transform<ComponentList, AddComponentHandle2<brigand::_1>>;
    
    
    int main()
    {
        static_assert(std::is_same<ComponentHandleList,
                                    brigand::list<
                                        entityx::ComponentHandle<TransformComponent>,
                                        entityx::ComponentHandle<ObjectComponent>,
                                        entityx::ComponentHandle<BodyComponent>
                                    >
                      >::value
                     );
        static_assert(std::is_same<ComponentHandleList2,
                                    brigand::list<
                                        entityx::ComponentHandle<TransformComponent>,
                                        entityx::ComponentHandle<ObjectComponent>,
                                        entityx::ComponentHandle<BodyComponent>
                                    >
                      >::value
                     );
    }
    

    【讨论】:

      【解决方案2】:

      你可以使用

      template<typename, template<typename...> class>
      struct apply {};
      
      template<template<typename...> class T, template<typename...> class List, typename ... Ts>
      struct apply<List<Ts...>, T> {
          using type = List<T<Ts>...>;
      };
      

      可以这样使用

      template<typename...>
      struct A {};
      
      template<typename...>
      struct B {};
      
      int main()
      {
          static_assert(std::is_same<apply<A<int, bool>, B>::type, A<B<int>, B<bool>>>::value);
      }
      

      【讨论】:

      • 我的问题不是很清楚,我不是在问如何将类型列表转换为带有指针的类型列表。我想知道的是如何将类型列表转换为类型的包装器列表,例如: List -> List, Wrapper>
      • @BryanTriana 已修复
      • 如果 brigand::list 是 template struct list{} 而不是您提出的 A 结构,我该如何做这个工作,即 template struct A {}。注意 ... 之后的 T,这是使用 brigand::list 时导致转换错误的原因。
      • @BryanTriana 它适用于 template&lt;typename... T&gt; struct list{} 而不是 A
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-24
      • 2010-10-19
      相关资源
      最近更新 更多