简体   繁体   English

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

[英]Recursive variadic template method operating on tuple

I'm trying to make a method which constructs a tuple from provided parameters, and 'fills' it recursively. 我正在尝试一种方法,该方法根据提供的参数构造一个元组,然后递归“填充”它。 Unfortunately, it yields compilation errors... This is the code: 不幸的是,它会产生编译错误...这是代码:

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

It's not self contained, but I've tested IntersectionComponents class and it works. 它不是自包含的,但是我已经测试了IntersectionComponents类并且可以工作。 Code breaks on allComponentsExist call. allComponentsExist调用上的代码中断。 It's template parameters probably need to be specified some other way... 它的模板参数可能需要以其他方式指定...

This is definition of IntersectionComponents class, in case it would be helpful: 如果有帮助,这是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 function returns reference to object in a tuple with the specified type(in template parameter). getByType函数返回对指定类型(在模板参数中)的元组中对象的引用。

Here's the error list from compiler(completely incomprehensible for me ;/): 这是来自编译器的错误列表(对我来说是完全无法理解的; /):

    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ę

Solved it. 解决了。 Well, it took 3 minutes or so after I've got 'genius' idea to just look at all error locations reported instead of trying to comprehend actual errors. 好吧,在我有了“天才”想法之后,花了3分钟左右的时间才查看报告的所有错误位置,而不是试图理解实际错误。 And I've searched for error in the wrong place, due to IDE which underlined following line in red: 而且我在错误的位置搜索了错误,这是由于IDE用红色强调了以下行:

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

Actual problem was this line: 实际的问题是此行:

components.set(currentComponent);

set() should get reference to object, but currentComponent was a pointer... changed it to: set()应该获得对对象的引用,但是currentComponent是一个指针...将其更改为:

components.set(*currentComponent);

And wall of errors is gone. 错误的墙已经消失了。

This line of errors made me realize this: 这行错误使我意识到了这一点:

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

Specifically "with ComponentType = BarComponent*" part :S 特别是“ with ComponentType = BarComponent *”部分:S

Anyway, sorry for bad question. 无论如何,对这个不好的问题感到抱歉。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM