我正在使用模板元编程制作一个实体组件系统库,以在编译时评估签名位集数据,并允许精确的位集大小,而无需使用#define MAX_COMPONENTS some-number
。
我正在使用Boost Hana,并具有应如下所示的功能:
template <auto T>
static constexpr Bitset signatureBitset = Bitset(
hana::fold(SignatureList[hana::integral_c<std::size_t, signatureID<T>>], 0,
[](auto l, auto r) {
return l | 1 << inferProperty<primitiveBit>(r);
}));
它的作用是为给定签名计算constexpr位集。签名是ECS组件和标签类型的 hana :: tuple_t 。
primitiveBit
返回模板参数类型组件/标签的位偏移量。由于 hana :: fold lambda不提供当前r
的类型,因此我不能简单地调用primitiveBit<RType>
(未定义RType)。
最简单的解决方案是编写每个模板“函数”的副本,但将其作为实际的constexpr函数而不是静态constexpr对象,但是我试图避免这样做,因为编写30多个重复的函数都可以这样做
template <typename T>
static constexpr auto inferFunctionName(hana::basic_type<T> t) {
return functionName<T>;
}
似乎很愚蠢,将使所有内容难以维护。上面的代码看起来也非常简单,就像可以使用模板函数(将模板constexpr对象作为模板参数)抽象出来一样。
这是我目前拥有的:
template <template<typename> typename TReturn, typename T>
constexpr auto inferProperty(hana::basic_type<T> t) {
return TReturn<T>();
}
inferProperty<primitiveBit>(r)
抛出编译错误,指出它与定义的模板签名不匹配。
由于template <template<typename T> typename TReturn, typename T>
未在lambda中定义,因此无法使用T
。
答案 0 :(得分:0)
如Jack C.在评论中所说,一种简单的解决方案是在lambda中使用decltype(r)
从对象获取类型,而不是通过模板函数推断类型。
这意味着propertyCheck<typename decltype(r)::type>
有效。