【问题标题】:hana types for template-of-templates模板模板的hana类型
【发布时间】:2017-12-07 11:40:02
【问题描述】:

我正在尝试使用 boost::hana 生成一个使用模板的类型,但遇到了麻烦。

我有以下课程

template<template<typename> typename BarModel>
struct Foo {
    BarModel<double> bar;
}

template<typename T>
struct BarOne {
    T x;
}

template<typename T>
struct BarTwo {
    T y;
}

我现在想为每个 BarX&lt;T&gt; 类创建一个 Foo&lt;BarImpl&gt;:

auto bar_types = hana::tuple_t<hana::template_t<BarOne>, hana::template_t<BarTwo>>;

hana::for_each(bar_types, [](auto t) {
    auto footype = SOMETHING(t);
});

问题,我不确定这应该怎么做。 我的第一次尝试是做

using BarT = typename decltype(t)::type;
auto bar_t = BarT(); // template_t, can create BarX<T> classes

auto foo_t = hana::template_<Foo>; // <-- FAIL
auto foo_bar_t = foo_t(bar_t);

但这失败了

error: type/value mismatch at argument 1 in template parameter list for ‘template<template<class ...> class F> constexpr const boost::hana::template_t<F> boost::hana::template_<F>’

note:   expected a template of type ‘template<class ...> class F’, got ‘template<template<class> class BarModel> class Foo’

注释表明hana::template_ 不适用于模板模板。 是这样吗?如果有,是否有替代解决方案?

【问题讨论】:

    标签: c++ templates boost-hana


    【解决方案1】:

    Boost.Hana 不直接支持这个,但是对于这种情况实现它只是几行代码。

    检查一下:

    #include <boost/hana.hpp>
    
    namespace hana = boost::hana;
    
    template <template <template <typename...> class> class F>
    struct template_template_t
    {
      template <template <typename...> class G>
      constexpr auto operator()(hana::basic_type<hana::template_t<G>>) const
        -> hana::type<F<G>>
      { return {}; }
    };
    
    template <template <template <typename...> class> class F>
    constexpr auto template_template = template_template_t<F>{};
    
    /*****/
    
    template <template <typename...> class BarModel>
    struct Foo {
      BarModel<double> bar;
    };
    
    template <typename T>
    struct BarOne {
      T x;
    };
    
    template <typename T>
    struct BarTwo {
      T y;
    };
    
    int main() {
      constexpr auto bar_types = hana::tuple_t<hana::template_t<BarOne>, hana::template_t<BarTwo>>;
    
      BOOST_HANA_CONSTANT_ASSERT(hana::equal(
        hana::transform(bar_types, template_template<Foo>)
      , hana::tuple_t<Foo<BarOne>, Foo<BarTwo>>
      ));
    }
    

    【讨论】:

    • 这似乎可行,谢谢!由于我的模板类被声明为template &lt;template &lt;typename&gt; class BarModel&gt; 而不是template &lt;template &lt;typename...&gt; class BarModel&gt;,我还必须从所有代码中删除省略号。我不确定我是否理解他们在这里的目的,需要详细说明吗?
    • 这应该意味着它匹配零个或多个类型名模板参数。我想它必须与签名完全匹配,这可能就是它不在库中的原因。 en.cppreference.com/w/cpp/language/parameter_pack
    • 说实话,我从来没有想过这个用例;这就是它不在图书馆的原因。但是你的观察是一个很好的理由将它们排除在图书馆之外(或者修复语言,因为这看起来很奇怪)。
    • @LouisDionne 也许已经解决了。这目前仅在 Clang 中部分实现:open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0522r0.html
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-22
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 2014-01-29
    • 2018-02-21
    • 1970-01-01
    相关资源
    最近更新 更多