将模板化的constexpr传递给函数来推断自动对象的类型

时间:2019-09-17 02:05:01

标签: c++ templates lambda template-meta-programming boost-hana

我正在使用模板元编程制作一个实体组件系统库,以在编译时评估签名位集数据,并允许精确的位集大小,而无需使用#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

1 个答案:

答案 0 :(得分:0)

如Jack C.在评论中所说,一种简单的解决方案是在lambda中使用decltype(r)从对象获取类型,而不是通过模板函数推断类型。

这意味着propertyCheck<typename decltype(r)::type>有效。