5

在a 中更新值(给定键和新值)boost::hana::map的规范方法是什么?

我尝试使用boost::hana::replace_if但它不起作用,map因为它不是 a Functor- 我可以通过将 a 转换map为 atuple然后再转换回 a来使其工作map,但这听起来效率低下。

我目前正在使用的替代方法是调用map::erase_key后跟map::insert.

是否有为此目的而设计的任何功能replace或功能我可能会丢失?update或者这是更新值的“规范”方式?

4

2 回答 2

4

我认为目前没有规范的方法可以做到这一点。如果有有效的用例,也许我们可以在那里获得一个函数来支持它。问题hana::erase_key在于您将创建一个新地图,然后再次使用hana::insert. 目前,使用hana::unpack然后创建新地图可能是您最好的选择。

#include <boost/hana.hpp>

namespace hana = boost::hana;

template <typename NewPair>
struct replace_helper_t
{
  NewPair const& new_pair;

  template <typename Pair>
  constexpr decltype(auto) operator()(Pair&& p) const
  {
    return hana::if_(
      hana::equal(hana::first(new_pair), hana::first(p)),
      new_pair,
      std::forward<Pair>(p)
    );
  }
};

struct replace_t
{
  template <typename Map, typename NewPair>
  constexpr auto operator()(Map&& m, NewPair&& new_pair) const
  {
    return hana::unpack(std::forward<Map>(m),
      hana::on(
        hana::make_map,
        replace_helper_t<NewPair>{std::forward<NewPair>(new_pair)}
      )
    );
  }
};

constexpr replace_t replace{};

int main()
{
  auto my_map = hana::make_map(
    hana::make_pair(hana::int_c<7>, 7),
    hana::make_pair(hana::int_c<13>, 13),
    hana::make_pair(hana::int_c<23>, 23)
  );

  auto new_map = replace(my_map, hana::make_pair(hana::int_c<13>, 14.0f));

  BOOST_HANA_RUNTIME_ASSERT(new_map ==
    hana::make_map(
      hana::make_pair(hana::int_c<7>, 7),
      hana::make_pair(hana::int_c<13>, 14.0f),
      hana::make_pair(hana::int_c<23>, 23)
    )
  );
}

另一方面,也许hana::map应该是Functor.

于 2016-05-23T22:16:41.150 回答
2

您需要更改值的类型吗?如果没有,并且如果您的值可以分配给,您可以使用map[key] = new_valueor 等​​价地hana::at_key(map, key) = new_value, ashana::at_key返回一个引用。

如果您需要更改值的类型,那就更棘手了。我们将无法就地执行任何操作,因为替换值后的映射类型将不同于替换值之前的类型。因此,我们必须创建一个新地图或该地图的某种修改视图(但当前不支持视图)。使用erase_keyandinsert确实会导致创建两个映射,效率低下。相反,我们可以提供某种update功能来实现相同的功能,但只会创建地图的一个副本(结果)。我相信通过提供我们自己的函数,我们也可以在编译时间方面做得比erase_key+更好。insert我打开了这个问题跟踪您的请求,因为我认为提供这样的内容很重要;谢谢。

最后,我想评论一下 Jason 所说的话:

另一方面,也许 hana::map 应该是一个仿函数。

hana::map可以制作一个 Functor,但我不确定它transform是否可以在仍然尊重 Functor 定律的同时触摸地图的键。如果不是这种情况,您仍然无法使用 eg 说“如果键满足某个谓词,则将值替换为 XXX” hana::replace_if。我尝试(但到目前为止失败)找到一个函数的例子,如果hana::transform基本上改变了底层键/值对的序列,就会违反法律,但我的直觉是找到这样的例子是可能的。在第 278 期继续。

于 2016-05-24T22:28:54.720 回答