c++ - C++ 中的关联键到键映射

标签 c++ c++11 boost stl containers

我正在搜索 C++ 中的“Key to Key”映射之类的东西。

我的意图如下:

  • 每个键 - 无论是在“左”还是“右”边都是唯一的
  • 左边的键可以通过右边的键查找,反之亦然

举个例子,为了让我的意图更清楚,在代码中,它可能看起来像:

key2key<int, string> myMap; // int maps to string, string to int

myMap.insert(0, "zero");
myMap.insert(1, "one");
myMap.insert(2, "two");

myMap.insert(1, "zero"); // would throw an error
myMap.insert(9, "one"); // would throw an error as well

cout << myMap.lookupLeft(1) << endl; // prints "one"
cout << myMap.lookupRight("one") << endl; // prints "1"

当然,我可以继续自己实现类似的东西,但是那里有什么东西吗? 我不想重新发明轮子,所以也许可以修改或重用标准的 STL 容器或 boost。

为什么我认为它有用?

假设您正在读取一个配置文件,并且您还想写入或更改此配置文件。 此配置文件可能包含一些在 C++ 内部表示为类型安全枚举类的字段。 使用“Key to Key”映射是一种非常轻量级的生成器和这些值的类型转换器。

enum class DebugLevel {error, warning, debug};
const key2key<DebugLevel, string> debugLevelMap = {
  {DebugLevel::error, "error"},
  {DebugLevel::warning, "warning"},
  {DebugLevel::debug, "debug"},
}

DebugLevel foo = debugLevelMap.lookupRight("error");
string bar = debugLevelMap.lookupLeft(DebugLevel::warning);

最佳答案

当我发布我的第一个答案时,我并不知道像 boost::bimap 这样的东西存在。我同意滚动您自己的双向 map 可能不如使用可能非常高质量的 Boost 实现。如果您的项目已经依赖于 Boost,则更是如此。如果您最担心的是 boost::bimap 缺少初始化列表构造函数,您可以轻松地将该功能添加为工厂函数。

#include <initializer_list>
#include <iostream>
#include <stdexcept>
#include <string>
#include <utility>

#include <boost/bimap.hpp>

template<typename T1, typename T2>
boost::bimap<T1, T2>
make_bimap(const std::initializer_list<std::pair<T1, T2>> initlist)
{
  using bimap_type = boost::bimap<T1, T2>;
  using value_type = typename bimap_type::value_type;
  bimap_type bimap {};
  for (const auto& iter : initlist)
    {
      if (!bimap.insert(value_type {iter.first, iter.second}).second)
        throw std::invalid_argument {"already mapped"};
    }
  return bimap;
}

int
main()
{
  using namespace std::literals;
  const auto bimap = make_bimap<int, std::string>({
      {0, "zero"s},
      {1, "one"s},
      {2, "two"s},
   // {1, "zero"s},  // would throw
   // {9, "one"s},   // would throw
  });
  std::cout << bimap.left.at(1) << std::endl;
  std::cout << bimap.right.at("one") << std::endl;
  return 0;
}

输出:

one
1

最初提到 boost::bimap 的功劳归于@ Pradhan .

关于c++ - C++ 中的关联键到键映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28551751/

相关文章:

c++ - 为什么我不能在 std::vector 中使用抽象类?

c++ - 读取文本文件并随机播放

c++ - 如何防止 iostreams::mapped_file_sink 创建可执行 txt 文件

c++ - 如何初始化 std::array<std::array<T, 2>, 2> 的对象?

c++ - SFINAE 用作返回类型,但不是参数类型

c++ - 是否可以将 X 的容器声明为 X 的成员

c++ - 了解 Makefile 的依赖关系 (C++)

C++ fscanf() 返回 -1 并且不覆盖变量

c++ - #define/#undef 是具有特殊含义的标识符的未定义行为吗?

c++ - 如何使用 C++ Boost 解析 JSON 数组?