【问题标题】:Merging multiple maps合并多个地图
【发布时间】:2016-08-25 14:22:46
【问题描述】:

我已经在 boost 邮件列表上问过这个问题,但我并不清楚我的意图。也可能是我没有完全理解如何做到这一点。

我想在hana中合并多张地图,见以下代码示例:

constexpr auto m1 = hana::make_map(
    hana::make_pair("key1"_s, hana::type_c<std::string>),
    hana::make_pair("key2"_s, hana::type_c<std::string>)
);

constexpr auto m2 = hana::make_map(
    hana::make_pair("key3"_s, hana::type_c<std::string>),
    hana::make_pair("key4"_s, hana::type_c<std::string>),
    hana::make_pair("key5"_s, hana::type_c<std::string>)
);

constexpr auto m3 = hana::make_map(
    hana::make_pair("key6"_s, hana::type_c<std::string>),
    hana::make_pair("key7"_s, hana::type_c<std::string>),
    hana::make_pair("key8"_s, hana::type_c<std::string>)
);

我已经得到了如何为两张地图执行此操作的答案:

constexpr auto result = hana::fold_left(m1, m2, hana::insert);
constexpr auto expected = hana::make_map(
    hana::make_pair("key1"_s, hana::type_c<std::string>),
    hana::make_pair("key2"_s, hana::type_c<std::string>),
    hana::make_pair("key3"_s, hana::type_c<std::string>),
    hana::make_pair("key4"_s, hana::type_c<std::string>),
    hana::make_pair("key5"_s, hana::type_c<std::string>)
);

当我查看文档时,我可以看到 fold_left 需要 2 或 3 个参数。

看起来我需要类似的东西: fold_left(fold_left(m1, m3, hana::insert), m2, hana::insert);

template<typename Map...>
constexpr auto merge_multiple_maps(Map... args) {
  // do something useful here...
}

但我不知道如何从这里开始,而且我在元编程方面仍然没有太多经验......

问候,马蒂斯

【问题讨论】:

  • 你是如何编译你的例子的?我在 C++14 和 GCC 7.3.0 上不断收到error: unable to find string literal operator ‘operator""_s’ with ‘const char [5]’, ‘long unsigned int’ arguments hana::make_pair("key1"_s, hana::type_c&lt;std::string&gt;)

标签: c++ c++14 boost-hana


【解决方案1】:

首先,定义merge2如下:

auto merge2 = [](auto&& m1, auto&& m2) {
  return hana::fold_left(std::forward<decltype(m1)>(m1),
                         std::forward<decltype(m2)>(m2),
                         hana::insert);
};

然后,将merge定义为merge2的递归应用:

auto merge = [](auto&& m1, auto&& ...ms) {
  return hana::fold_left(
    hana::make_basic_tuple(std::forward<decltype(ms)>(ms)...),
    std::forward<decltype(m1)>(m1),
    merge2
  );
};

我没有测试这个实现,但它应该会给你这个想法。如果你不关心完美转发,你可以放弃所有static_cast;这只是为了提高运行时效率,以防您在地图中存储复制成本高但移动成本低的类型。此外,您将无法在 constexpr 上下文中使用它,因为 lambda 不能出现在常量表达式中。这将在 C++17 中修复,但现在您可以很容易地实现与这些 lambda 等效的函数对象。

[编辑:Hana 可能会在未来的某个时候实现这个merge 函数。] [编辑:使用std::forward 而不是static_cast。]

【讨论】:

  • 不应该 std::forward&lt;decltype(m1)&gt;(m1) 工作,用于自我记录吗?
  • 是的,对不起。我有在 Hana 的实现中使用 static_cast 的习惯,因为它会减少 1 个函数实例化(这对 Hana 有影响),但我会编辑我的答案,因为 std::forward 更清晰。
猜你喜欢
  • 2012-03-21
  • 2017-12-25
  • 2018-04-17
  • 1970-01-01
  • 2022-11-04
  • 2012-02-06
  • 1970-01-01
  • 2019-10-20
  • 1970-01-01
相关资源
最近更新 更多