简体   繁体   English

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

[英]How to transform a boost::hana::map into lambdas

I have the following code我有以下代码

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);

but I always get the error message但我总是收到错误消息

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

when I use hana::pair in my_tuple .当我在my_tuple中使用hana::pair时。 All works fine when I just use当我使用时一切正常

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

and obviously no call to hana::first显然没有打电话给hana::first

Why do I get back kind of a reference when using hana::first ?为什么我在使用hana::first时会得到某种参考?

It's not clear why you are trying to use hana::map .目前尚不清楚您为什么要尝试使用hana::map hana::map is not a Functor and has no implementation for hana::transform . hana::map不是Functor并且没有实现hana::transform It is, however Foldable so you could use hana::unpack and return a new tuple of lambdas if you needed to.但是它是Foldable的,因此您可以使用hana::unpack并在需要时返回一个新的 lambda 元组。

As for hana::first along with other accessors including hana::at , hana::at_key , etc.;至于hana::first以及其他访问器,包括hana::athana::at_key等; They all return reference types so to access members you must strip the reference somehow.它们都返回引用类型,因此要访问成员,您必须以某种方式剥离引用。

For this you can use the provided hana::type unary + operator:为此,您可以使用提供的hana::type一元+运算符:

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

Or you can use hana::typeid_ which is a bit more readable in my opinion:或者您可以使用hana::typeid_在我看来更具可读性:

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

I'm not sure if hana::map fits with your use case, but here is how you could "transform" it into a tuple of lambdas:我不确定hana::map是否适合您的用例,但这是您如何将其“转换”为 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 https://godbolt.org/z/KMdrzS

From your code example, note that you might also run into issues taking a mutable reference to a variant that is being implicitly cast from a different type so I just removed that.从您的代码示例中,请注意,您可能还会遇到对从不同类型隐式转换的变体进行可变引用的问题,因此我只是将其删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM