【问题标题】:Passing templated constexpr to function inferring type of auto object将模板化的 constexpr 传递给函数推断自动对象的类型
【发布时间】:2020-01-17 20:33:46
【问题描述】:

我正在制作一个实体组件系统库,利用模板元编程在编译时评估签名位集数据,并允许在不使用#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 Bitset。签名是 ECS 组件和标签类型的 hana::tuple_tprimitiveBit 返回模板参数类型组件/标签的位偏移量。由于hana::fold lambda 不提供当前r 的类型,我不能简单地调用primitiveBit&lt;RType&gt;(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&lt;primitiveBit&gt;(r) 抛出一个编译错误,说它与定义的模板签名不匹配。

由于 T 未在 lambda 中定义,因此不能使用 template &lt;template&lt;typename T&gt; typename TReturn, typename T&gt;

【问题讨论】:

  • 有什么原因decltype(r) 在 lambda 中不起作用?
  • @JackC。类型被包裹在 hana::basic_type 中,所以 decltype(r) 是 hana::basic_type。经过一番折腾,typename decltype(r)::type 才是真正的解决方案。

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


【解决方案1】:

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

这意味着propertyCheck&lt;typename decltype(r)::type&gt; 有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 2013-02-17
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 2017-12-25
    • 1970-01-01
    相关资源
    最近更新 更多