如何将 boost::hana::map 转换为 lambda

How to transform a boost::hana::map into lambdas

我有以下代码

template <typename T>
void my_func(T& /*var*/)
{
};

auto my_types = hana::make_map(
  hana::make_pair(hana::type_c<std::uint32_t>, hana::integral_c<std::uint8_t, 1>),
  hana::make_pair(hana::type_c<std::uint16_t>, hana::integral_c<std::uint8_t, 1>)
);

using my_variant = std::variant<std::uint32_t, std::uint16_t>;

auto to_factory = [](auto map)
{
  return hana::transform(map, [](auto pair)
    {
      return [](my_variant& value)
        {
          using T = typename decltype(hana::first(pair))::type;
          T v;
          my_func(v);
          value = v;
        };
    });
};

auto factory = to_factory(my_types);

但我总是收到错误消息

error: 'boost::hana::type_impl<short unsigned int>::_&' is not a class, struct, or union type

当我在 my_tuple 中使用 hana::pair 时。当我只使用

时一切正常
auto my_types = hana::make_map(
  hana::type_c<std::uint32_t>,
  hana::type_c<std::uint16_t>
);

显然没有调用 hana::first

为什么我在使用 hana::first 时会返回某种参考?

不清楚您尝试使用 hana::map 的原因。 hana::map 不是 Functor,并且没有 hana::transform 的实现。但是,它是 Foldable,因此如果需要,您可以使用 hana::unpack 和 return 一个新的 lambda 元组。

至于 hana::first 以及其他访问器,包括 hana::athana::at_key 等;它们都是 return 引用类型,因此要访问成员,您必须以某种方式去除引用。

为此,您可以使用提供的 hana::type 一元 + 运算符:

using type = typename decltype(+hana::first(x))::type;

或者您可以使用 hana::typeid_,我认为它更具可读性:

using type = typename decltype(hana::typeid_(hana::first(x)))::type;

我不确定 hana::map 是否适合您的用例,但可以通过以下方式将其 "transform" 放入 lambda 元组中:

#include <boost/hana.hpp>
#include <cstdint>
#include <variant>

namespace hana = boost::hana;


auto my_types = hana::make_map(
    hana::make_pair(hana::type_c<std::uint32_t>, hana::integral_c<std::uint8_t, 1>),
    hana::make_pair(hana::type_c<std::uint16_t>, hana::integral_c<std::uint8_t, 1>)
);

using my_variant = std::variant<std::uint32_t, std::uint16_t>;
auto make_lambda = [](auto pair) {
    return [](my_variant value) {
        using T = typename decltype(hana::typeid_(hana::first(pair)))::type;
        // do stuff
    };
};

auto to_factory = [](auto map) {
    return hana::unpack(map, [](auto ...pairs) {
        return hana::make_tuple(make_lambda(pairs)...);
    });
};

// erm.. you could also do this
auto to_factory_2 = [](auto map) {
    return hana::unpack(map, [](auto ...pairs) {
        return hana::make_tuple(((void)pairs, [](my_variant value) {
            using T = typename decltype(hana::typeid_(hana::first(pairs)))::type;
            // do stuff
        })...);
    });
}

https://godbolt.org/z/KMdrzS

从您的代码示例中,请注意,您可能还会 运行 遇到问题,即对从不同类型隐式转换的变体进行可变引用,因此我将其删除。