【发布时间】:2015-08-08 13:22:12
【问题描述】:
我正在尝试创建一个从提供的参数构造元组并递归“填充”它的方法。不幸的是,它会产生编译错误......这是代码:
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ę
【问题讨论】:
-
您提供的代码不允许有人重现您的问题,请尝试缩小您的问题陈述范围或提供MCVE
-
啊,好吧...我做了一个独立的例子,它可以工作。它一定是其他的......对不起这个问题。修复后我会写出问题所在:S
-
根据错误信息,您的索引似乎是
std::tuple中的一个超出范围的索引。此外,它错过了allComponentsExist的递归结束:template<typename IntersectComponents/*, typename Head*/> bool allComponentsExist的重载在哪里? -
嗯,你是对的。基本上我在请求不在元组中的 std::tuple 元素。关于超载,我认为我有一个很明显,所以我在这里省略了它:S
标签: c++ templates c++11 tuples variadic-templates