[英]Recursive variadic template method operating on tuple
我正在嘗試一種方法,該方法根據提供的參數構造一個元組,然后遞歸“填充”它。 不幸的是,它會產生編譯錯誤...這是代碼:
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ę
解決了。 好吧,在我有了“天才”想法之后,花了3分鍾左右的時間才查看報告的所有錯誤位置,而不是試圖理解實際錯誤。 而且我在錯誤的位置搜索了錯誤,這是由於IDE用紅色強調了以下行:
allComponentsExist<IntersectionComponents<Head, Tail...>, Tail...>(headComponent.entityID, currentEntityRequiredComponents));
實際的問題是此行:
components.set(currentComponent);
set()應該獲得對對象的引用,但是currentComponent是一個指針...將其更改為:
components.set(*currentComponent);
錯誤的牆已經消失了。
這行錯誤使我意識到了這一點:
...componentsManager.h:27:34: required from ‘void IntersectionComponents<ComponentTypes>::set(ComponentType&) [with ComponentType = BarComponent*; ComponentTypes = {FooComponent, BarComponent}]’
特別是“ with ComponentType = BarComponent *”部分:S
無論如何,對這個不好的問題感到抱歉。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.