在元组上运行的递归可变参数模板方法

时间:2015-08-08 13:22:13

标签: c++ templates c++11 tuples variadic-templates

我试图制作一个从提供的参数构造元组的方法,然后填充'它是递归的。不幸的是,它会产生编译错误......这就是代码:

template<typename Head, typename... Tail>
std::vector<IntersectionComponents<Head, Tail...>> intersection() {
    std::vector<IntersectionComponents<Head, Tail...>> results;

    auto& headComponents = *getAllComponents<Head>();
    for (auto& headComponent : headComponents) {
        IntersectionComponents<Head, Tail...> currentEntityRequiredComponents;
        if (allComponentsExist<IntersectionComponents<Head, Tail...>, Tail...>(headComponent.entityID, currentEntityRequiredComponents)) {
            currentEntityRequiredComponents.set(headComponent);
            results.push_back(std::move(currentEntityRequiredComponents));
        }
    }

    return results;
}

    template<typename IntersectComponents, typename Head, typename... Tail>
bool allComponentsExist(EntityID entityID, IntersectComponents& components) {
    auto currentComponent = getComponent<Head>(entityID);
    if (!currentComponent) {
        return false;
    }

    if (allComponentsExist<IntersectComponents, Tail...>(entityID, components)) {
        components.set(currentComponent);
        return true;
    }

    return false;
}

它不是自包含的,但我已经测试了IntersectionComponents类并且它可以工作。 allComponentsExist调用的代码中断。它的模板参数可能需要以其他方式指定......

这是IntersectionComponents类的定义,以防它有用:

template<typename... ComponentTypes>
class IntersectionComponents {
public:
    template<typename ComponentType>
    ComponentType& get() {
        return *getByType<ComponentType*>(components);
    }

private:
    std::tuple<ComponentTypes* ...> components;

    template<typename ComponentType>
    void set(ComponentType& component) {
        getByType<ComponentType*>(components) = &component;
    }

    friend class ComponentsManager;
};

getByType函数返回对具有指定类型的元组中对象的引用(在模板参数中)。

这里是编译器的错误列表(对我来说完全不可理解; /):

    In file included from /usr/include/c++/5.2.0/functional:55:0,
                 from /usr/include/c++/5.2.0/memory:79,
                 from /mnt/data/dev/Active/ECS/src/3party/catch.hpp:426,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:1:
/usr/include/c++/5.2.0/tuple: In instantiation of ‘struct std::tuple_element<1ul, std::tuple<BarComponent*> >’:
/usr/include/c++/5.2.0/tuple:755:12:   required from ‘struct std::tuple_element<2ul, std::tuple<FooComponent*, BarComponent*> >’
/usr/include/c++/5.2.0/tuple:769:69:   required by substitution of ‘template<long unsigned int __i, class _Tp> using __tuple_element_t = typename std::tuple_element::type [with long unsigned int __i = 2ul; _Tp = std::tuple<FooComponent*, BarComponent*>]’
/usr/include/c++/5.2.0/tuple:844:5:   required by substitution of ‘template<long unsigned int __i, class ... _Elements> constexpr std::__tuple_element_t<__i, std::tuple<_Elements ...> >&& std::get(std::tuple<_Elements ...>&&) [with long unsigned int __i = 2ul; _Elements = {FooComponent*, BarComponent*}]’
/mnt/data/dev/Active/ECS/src/utils/getTupleElementByID.h:31:103:   required from ‘T& getByType(std::tuple<_Elements ...>&) [with T = BarComponent**; TupleElems = {FooComponent*, BarComponent*}]’
/mnt/data/dev/Active/ECS/include/../src/core/componentsManager.h:27:34:   required from ‘void IntersectionComponents<ComponentTypes>::set(ComponentType&) [with ComponentType = BarComponent*; ComponentTypes = {FooComponent, BarComponent}]’
/mnt/data/dev/Active/ECS/include/../src/core/componentsManager.h:148:13:   required from ‘bool ComponentsManager::allComponentsExist(EntityID, IntersectComponents&) [with IntersectComponents = IntersectionComponents<FooComponent, BarComponent>; Head = BarComponent; Tail = {}; EntityID = unsigned int]’
/mnt/data/dev/Active/ECS/include/../src/core/componentsManager.h:118:83:   required from ‘std::vector<IntersectionComponents<Head, Tail ...> > ComponentsManager::intersection() [with Head = FooComponent; Tail = {BarComponent}]’
/mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:75:64:   required from here
/usr/include/c++/5.2.0/tuple:755:12: error: invalid use of incomplete type ‘struct std::tuple_element<0ul, std::tuple<> >’
     struct tuple_element<__i, tuple<_Head, _Tail...> >
            ^
In file included from /usr/include/c++/5.2.0/algorithm:60:0,
                 from /mnt/data/dev/Active/ECS/src/3party/catch.hpp:67,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:1:
/usr/include/c++/5.2.0/utility:85:11: note: declaration of ‘struct std::tuple_element<0ul, std::tuple<> >’
     class tuple_element;
           ^
In file included from /mnt/data/dev/Active/ECS/include/../src/core/componentsManager.h:4:0,
                 from /mnt/data/dev/Active/ECS/include/../src/core/engine.h:4,
                 from /mnt/data/dev/Active/ECS/./include/ecs/ecs.h:3,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:2:
/mnt/data/dev/Active/ECS/src/utils/getTupleElementByID.h: In instantiation of ‘T& getByType(std::tuple<_Elements ...>&) [with T = BarComponent**; TupleElems = {FooComponent*, BarComponent*}]’:
/mnt/data/dev/Active/ECS/include/../src/core/componentsManager.h:27:34:   required from ‘void IntersectionComponents<ComponentTypes>::set(ComponentType&) [with ComponentType = BarComponent*; ComponentTypes = {FooComponent, BarComponent}]’
/mnt/data/dev/Active/ECS/include/../src/core/componentsManager.h:148:13:   required from ‘bool ComponentsManager::allComponentsExist(EntityID, IntersectComponents&) [with IntersectComponents = IntersectionComponents<FooComponent, BarComponent>; Head = BarComponent; Tail = {}; EntityID = unsigned int]’
/mnt/data/dev/Active/ECS/include/../src/core/componentsManager.h:118:83:   required from ‘std::vector<IntersectionComponents<Head, Tail ...> > ComponentsManager::intersection() [with Head = FooComponent; Tail = {BarComponent}]’
/mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:75:64:   required from here
/mnt/data/dev/Active/ECS/src/utils/getTupleElementByID.h:31:103: error: no matching function for call to ‘get(std::tuple<FooComponent*, BarComponent*>&)’
     return std::get<detail::get_number_of_element_from_tuple_by_type_impl<T, 0, TupleElems...>::value>(t);
                                                                                                       ^
In file included from /usr/include/c++/5.2.0/algorithm:60:0,
                 from /mnt/data/dev/Active/ECS/src/3party/catch.hpp:67,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:1:
/usr/include/c++/5.2.0/utility:147:5: note: candidate: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(std::pair<_Tp1, _Tp2>&)
     get(std::pair<_Tp1, _Tp2>& __in) noexcept
     ^
/usr/include/c++/5.2.0/utility:147:5: note:   template argument deduction/substitution failed:
In file included from /mnt/data/dev/Active/ECS/include/../src/core/componentsManager.h:4:0,
                 from /mnt/data/dev/Active/ECS/include/../src/core/engine.h:4,
                 from /mnt/data/dev/Active/ECS/./include/ecs/ecs.h:3,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:2:
/mnt/data/dev/Active/ECS/src/utils/getTupleElementByID.h:31:103: note:   ‘std::tuple<FooComponent*, BarComponent*>’ is not derived from ‘std::pair<_Tp1, _Tp2>’
     return std::get<detail::get_number_of_element_from_tuple_by_type_impl<T, 0, TupleElems...>::value>(t);
                                                                                                       ^
In file included from /usr/include/c++/5.2.0/algorithm:60:0,
                 from /mnt/data/dev/Active/ECS/src/3party/catch.hpp:67,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:1:
/usr/include/c++/5.2.0/utility:152:5: note: candidate: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type&& std::get(std::pair<_Tp1, _Tp2>&&)
     get(std::pair<_Tp1, _Tp2>&& __in) noexcept
     ^
/usr/include/c++/5.2.0/utility:152:5: note:   template argument deduction/substitution failed:
In file included from /mnt/data/dev/Active/ECS/include/../src/core/componentsManager.h:4:0,
                 from /mnt/data/dev/Active/ECS/include/../src/core/engine.h:4,
                 from /mnt/data/dev/Active/ECS/./include/ecs/ecs.h:3,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:2:
/mnt/data/dev/Active/ECS/src/utils/getTupleElementByID.h:31:103: note:   ‘std::tuple<FooComponent*, BarComponent*>’ is not derived from ‘std::pair<_Tp1, _Tp2>’
     return std::get<detail::get_number_of_element_from_tuple_by_type_impl<T, 0, TupleElems...>::value>(t);
                                                                                                       ^
In file included from /usr/include/c++/5.2.0/algorithm:60:0,
                 from /mnt/data/dev/Active/ECS/src/3party/catch.hpp:67,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:1:
/usr/include/c++/5.2.0/utility:157:5: note: candidate: template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr const typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(const std::pair<_Tp1, _Tp2>&)
     get(const std::pair<_Tp1, _Tp2>& __in) noexcept
     ^
/usr/include/c++/5.2.0/utility:157:5: note:   template argument deduction/substitution failed:
In file included from /mnt/data/dev/Active/ECS/include/../src/core/componentsManager.h:4:0,
                 from /mnt/data/dev/Active/ECS/include/../src/core/engine.h:4,
                 from /mnt/data/dev/Active/ECS/./include/ecs/ecs.h:3,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:2:
/mnt/data/dev/Active/ECS/src/utils/getTupleElementByID.h:31:103: note:   ‘std::tuple<FooComponent*, BarComponent*>’ is not derived from ‘const std::pair<_Tp1, _Tp2>’
     return std::get<detail::get_number_of_element_from_tuple_by_type_impl<T, 0, TupleElems...>::value>(t);
                                                                                                       ^
In file included from /usr/include/c++/5.2.0/algorithm:60:0,
                 from /mnt/data/dev/Active/ECS/src/3party/catch.hpp:67,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:1:
/usr/include/c++/5.2.0/utility:166:5: note: candidate: template<class _Tp, class _Up> constexpr _Tp& std::get(std::pair<_T1, _T2>&)
     get(pair<_Tp, _Up>& __p) noexcept
     ^
/usr/include/c++/5.2.0/utility:166:5: note:   template argument deduction/substitution failed:
/usr/include/c++/5.2.0/utility:171:5: note: candidate: template<class _Tp, class _Up> constexpr const _Tp& std::get(const std::pair<_T1, _T2>&)
     get(const pair<_Tp, _Up>& __p) noexcept
     ^
/usr/include/c++/5.2.0/utility:171:5: note:   template argument deduction/substitution failed:
/usr/include/c++/5.2.0/utility:176:5: note: candidate: template<class _Tp, class _Up> constexpr _Tp&& std::get(std::pair<_T1, _T2>&&)
     get(pair<_Tp, _Up>&& __p) noexcept
     ^
/usr/include/c++/5.2.0/utility:176:5: note:   template argument deduction/substitution failed:
/usr/include/c++/5.2.0/utility:181:5: note: candidate: template<class _Tp, class _Up> constexpr _Tp& std::get(std::pair<_Up, _Tp>&)
     get(pair<_Up, _Tp>& __p) noexcept
     ^
/usr/include/c++/5.2.0/utility:181:5: note:   template argument deduction/substitution failed:
/usr/include/c++/5.2.0/utility:186:5: note: candidate: template<class _Tp, class _Up> constexpr const _Tp& std::get(const std::pair<_Up, _Tp>&)
     get(const pair<_Up, _Tp>& __p) noexcept
     ^
/usr/include/c++/5.2.0/utility:186:5: note:   template argument deduction/substitution failed:
/usr/include/c++/5.2.0/utility:191:5: note: candidate: template<class _Tp, class _Up> constexpr _Tp&& std::get(std::pair<_Up, _Tp>&&)
     get(pair<_Up, _Tp>&& __p) noexcept
     ^
/usr/include/c++/5.2.0/utility:191:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/5.2.0/tuple:39:0,
                 from /usr/include/c++/5.2.0/functional:55,
                 from /usr/include/c++/5.2.0/memory:79,
                 from /mnt/data/dev/Active/ECS/src/3party/catch.hpp:426,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:1:
/usr/include/c++/5.2.0/array:280:5: note: candidate: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr _Tp& std::get(std::array<_Tp, _Nm>&)
     get(array<_Tp, _Nm>& __arr) noexcept
     ^
/usr/include/c++/5.2.0/array:280:5: note:   template argument deduction/substitution failed:
In file included from /mnt/data/dev/Active/ECS/include/../src/core/componentsManager.h:4:0,
                 from /mnt/data/dev/Active/ECS/include/../src/core/engine.h:4,
                 from /mnt/data/dev/Active/ECS/./include/ecs/ecs.h:3,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:2:
/mnt/data/dev/Active/ECS/src/utils/getTupleElementByID.h:31:103: note:   ‘std::tuple<FooComponent*, BarComponent*>’ is not derived from ‘std::array<_Tp, _Nm>’
     return std::get<detail::get_number_of_element_from_tuple_by_type_impl<T, 0, TupleElems...>::value>(t);
                                                                                                       ^
In file included from /usr/include/c++/5.2.0/tuple:39:0,
                 from /usr/include/c++/5.2.0/functional:55,
                 from /usr/include/c++/5.2.0/memory:79,
                 from /mnt/data/dev/Active/ECS/src/3party/catch.hpp:426,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:1:
/usr/include/c++/5.2.0/array:289:5: note: candidate: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr _Tp&& std::get(std::array<_Tp, _Nm>&&)
     get(array<_Tp, _Nm>&& __arr) noexcept
     ^
/usr/include/c++/5.2.0/array:289:5: note:   template argument deduction/substitution failed:
In file included from /mnt/data/dev/Active/ECS/include/../src/core/componentsManager.h:4:0,
                 from /mnt/data/dev/Active/ECS/include/../src/core/engine.h:4,
                 from /mnt/data/dev/Active/ECS/./include/ecs/ecs.h:3,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:2:
/mnt/data/dev/Active/ECS/src/utils/getTupleElementByID.h:31:103: note:   ‘std::tuple<FooComponent*, BarComponent*>’ is not derived from ‘std::array<_Tp, _Nm>’
     return std::get<detail::get_number_of_element_from_tuple_by_type_impl<T, 0, TupleElems...>::value>(t);
                                                                                                       ^
In file included from /usr/include/c++/5.2.0/tuple:39:0,
                 from /usr/include/c++/5.2.0/functional:55,
                 from /usr/include/c++/5.2.0/memory:79,
                 from /mnt/data/dev/Active/ECS/src/3party/catch.hpp:426,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:1:
/usr/include/c++/5.2.0/array:297:5: note: candidate: template<long unsigned int _Int, class _Tp, long unsigned int _Nm> constexpr const _Tp& std::get(const std::array<_Tp, _Nm>&)
     get(const array<_Tp, _Nm>& __arr) noexcept
     ^
/usr/include/c++/5.2.0/array:297:5: note:   template argument deduction/substitution failed:
In file included from /mnt/data/dev/Active/ECS/include/../src/core/componentsManager.h:4:0,
                 from /mnt/data/dev/Active/ECS/include/../src/core/engine.h:4,
                 from /mnt/data/dev/Active/ECS/./include/ecs/ecs.h:3,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:2:
/mnt/data/dev/Active/ECS/src/utils/getTupleElementByID.h:31:103: note:   ‘std::tuple<FooComponent*, BarComponent*>’ is not derived from ‘const std::array<_Tp, _Nm>’
     return std::get<detail::get_number_of_element_from_tuple_by_type_impl<T, 0, TupleElems...>::value>(t);
                                                                                                       ^
In file included from /usr/include/c++/5.2.0/functional:55:0,
                 from /usr/include/c++/5.2.0/memory:79,
                 from /mnt/data/dev/Active/ECS/src/3party/catch.hpp:426,
                 from /mnt/data/dev/Active/ECS/tests/core/componentsManagerTests.cpp:1:
/usr/include/c++/5.2.0/tuple:832:5: note: candidate: template<long unsigned int __i, class ... _Elements> constexpr std::__tuple_element_t<__i, std::tuple<_Elements ...> >& std::get(std::tuple<_Elements ...>&)
     get(tuple<_Elements...>& __t) noexcept
     ^
/usr/include/c++/5.2.0/tuple:832:5: note:   template argument deduction/substitution failed:
/usr/include/c++/5.2.0/tuple:838:5: note: candidate: template<long unsigned int __i, class ... _Elements> constexpr std::__tuple_element_t<__i, std::tuple<_Elements ...> >& std::get(const std::tuple<_Elements ...>&)
     get(const tuple<_Elements...>& __t) noexcept
     ^
/usr/include/c++/5.2.0/tuple:838:5: note:   template argument deduction/substitution failed:
/usr/include/c++/5.2.0/tuple:844:5: note: candidate: template<long unsigned int __i, class ... _Elements> constexpr std::__tuple_element_t<__i, std::tuple<_Elements ...> >&& std::get(std::tuple<_Elements ...>&&)
     get(tuple<_Elements...>&& __t) noexcept
     ^
/usr/include/c++/5.2.0/tuple:844:5: note:   substitution of deduced template arguments resulted in errors seen above
/usr/include/c++/5.2.0/tuple:867:5: note: candidate: template<class _Tp, class ... _Types> constexpr _Tp& std::get(std::tuple<_Elements ...>&)
     get(tuple<_Types...>& __t) noexcept
     ^
/usr/include/c++/5.2.0/tuple:867:5: note:   template argument deduction/substitution failed:
/usr/include/c++/5.2.0/tuple:873:5: note: candidate: template<class _Tp, class ... _Types> constexpr _Tp&& std::get(std::tuple<_Elements ...>&&)
     get(tuple<_Types...>&& __t) noexcept
     ^
/usr/include/c++/5.2.0/tuple:873:5: note:   template argument deduction/substitution failed:
/usr/include/c++/5.2.0/tuple:879:5: note: candidate: template<class _Tp, class ... _Types> constexpr const _Tp& std::get(const std::tuple<_Elements ...>&)
     get(const tuple<_Types...>& __t) noexcept
     ^
/usr/include/c++/5.2.0/tuple:879:5: note:   template argument deduction/substitution failed:
CMakeFiles/tests.dir/build.make:77: polecenia dla obiektu 'CMakeFiles/tests.dir/tests/core/componentsManagerTests.cpp.o' nie powiodły się

1 个答案:

答案 0 :(得分:0)

解决了它。好吧,在我得到“天才”后花了3分钟左右的时间。想法只是查看报告的所有错误位置,而不是试图理解实际错误。我在错误的地方搜索错误,因为IDE强调下面的红线:

allComponentsExist<IntersectionComponents<Head, Tail...>, Tail...>(headComponent.entityID, currentEntityRequiredComponents));

实际问题是这一行:

components.set(currentComponent);

set()应该引用object,但是currentComponent是一个指针......改为:

components.set(*currentComponent);

错误之处已经消失。

这一系列的错误让我意识到了这一点:

...componentsManager.h:27:34:   required from ‘void IntersectionComponents<ComponentTypes>::set(ComponentType&) [with ComponentType = BarComponent*; ComponentTypes = {FooComponent, BarComponent}]’

具体而言#34; ComponentType = BarComponent *&#34;部分:S

无论如何,对不好的问题感到抱歉。