C++ 为什么在循环boost::hana::tuple时会得到意外的索引

C++ 为什么在循环boost::hana::tuple时会得到意外的索引,c++,lambda,c++17,variant,boost-hana,C++,Lambda,C++17,Variant,Boost Hana,这是我的密码 using my_variant = std::variant<std::uint32_t, std::int32_t>; auto my_types_map = hana::make_tuple( hana::make_pair(hana::type_c<std::uint32_t>, hana::integral_c<std::uint8_t, 0>), hana::make_pair(hana::type_c<std::in

这是我的密码

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

auto my_types_map = hana::make_tuple(
  hana::make_pair(hana::type_c<std::uint32_t>, hana::integral_c<std::uint8_t, 0>),
  hana::make_pair(hana::type_c<std::int32_t>,  hana::integral_c<std::uint8_t, 1>) 
);

template <typename T>
void my_func(T& value)
{
  value = 32;
};

auto factory(std::uint8_t code, my_variant& value)
{
  std::function<void(my_variant&)> sub_fun;
  hana::for_each(my_types_map, [&](const auto& x)
    {
      if (code == hana::second(x))
      {
        using T = typename decltype(+hana::first(x))::type;
        sub_fun = [](my_variant& v){ my_func(std::get<T>(v)); };
      }
    });
  sub_fun(value);
}

这里的问题是什么?

问题是您的setter希望该变量已经具有预期的类型

你应该:

auto factory(std::uint8_t code, my_variant& value)
{
  std::function<void(my_variant&)> sub_fun;
  hana::for_each(my_types_map, [&](const auto& x)
    {
      if (code == hana::second(x))
      {
        using T = typename decltype(+hana::first(x))::type;
        sub_fun = [](my_variant& v){ T t; my_func(t); v = t; };
      }
    });
  sub_fun(value);
}
自动工厂(标准::uint8\u t代码、我的变量和值)
{
std::功能子功能;
hana::for_each(我的_类型_映射,[&](const auto&x)
{
如果(代码==hana::秒(x))
{
使用T=typename decltype(+hana::first(x))::type;
sub_fun=[](my_variant&v){T;my_func(T);v=T;};
}
});
sub_fun(价值);
}

问题在于,您的setter希望该变量已经具有预期的类型

你应该:

auto factory(std::uint8_t code, my_variant& value)
{
  std::function<void(my_variant&)> sub_fun;
  hana::for_each(my_types_map, [&](const auto& x)
    {
      if (code == hana::second(x))
      {
        using T = typename decltype(+hana::first(x))::type;
        sub_fun = [](my_variant& v){ T t; my_func(t); v = t; };
      }
    });
  sub_fun(value);
}
自动工厂(标准::uint8\u t代码、我的变量和值)
{
std::功能子功能;
hana::for_each(我的_类型_映射,[&](const auto&x)
{
如果(代码==hana::秒(x))
{
使用T=typename decltype(+hana::first(x))::type;
sub_fun=[](my_variant&v){T;my_func(T);v=T;};
}
});
sub_fun(价值);
}

您的问题与Boost.Hana无关

这是一个简短的复制:

std::variant<int, char> v;
std::get<char>(v) = 'X'; // this throws

你的问题与Boost.Hana无关

这是一个简短的复制:

std::variant<int, char> v;
std::get<char>(v) = 'X'; // this throws

什么意思,
意外索引
。你的意思是你得到了一个
错误的变量\u访问权限
?你是什么意思,
意外索引
。你的意思是说你获得了一个
错误的变量访问权限
?但是当我只调用
我的变量v时,问题仍然存在;工厂(1,v);断言(32==std::get(v))
对我来说,这表明问题不在于
variant
(这个异常也不是一个
坏的\u variant\u access
)。@Reza应该是异常-你得到了什么异常(这也应该是个问题)。@Reza同样,不要使用Yoda条件<代码>断言(std::get(v)==32)。绝对没有理由向后写比较。这是一个
std::bad\u variant\u access
。异常只是有额外的描述性文本与之关联,但当我只调用
my_variant v;工厂(1,v);断言(32==std::get(v))
对我来说,这表明问题不在于
variant
(这个异常也不是一个
坏的\u variant\u access
)。@Reza应该是异常-你得到了什么异常(这也应该是个问题)。@Reza同样,不要使用Yoda条件<代码>断言(std::get(v)==32)。绝对没有理由向后写比较。这是一个
std::bad\u variant\u access
。该异常只包含与之关联的其他描述性文本。但此解决方案涉及一个额外副本,我希望通过更改
my_func
,您可以执行
v=my_func()
。但是这个解决方案需要一个额外的副本,我希望通过更改
my_func
,您可以执行
v=my_func()