C++ Boost Bimap示例详细讲解

 更新时间:2022年11月05日 17:18:41   作者:无水先生  
Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称

一、提要

库 Boost.Bimap 基于 Boost.MultiIndex 并提供了一个无需先定义即可立即使用的容器。该容器类似于 std::map,但支持从任一侧查找值。 Boost.Bimap 允许您根据访问地图的方式创建任意一侧都可以作为关键点的地图。当您访问左侧作为键时,右侧是值,反之亦然。

二、示例

Example13.1.Usingboost::bimap

#include <boost/bimap.hpp>
#include <string>
#include <iostream>
int main()
{
  typedef boost::bimap<std::string, int> bimap;
  bimap animals;
  animals.insert({"cat", 4});
  animals.insert({"shark", 0});
  animals.insert({"spider", 8});
  std::cout << animals.left.count("cat") << '\n';
  std::cout << animals.right.count(8) << '\n';
}

boost::bimap 定义在 boost/bimap.hpp 中,提供了两个成员变量 left 和 right ,可用于访问 boost::bimap 统一的两个 std::map 类型的容器。在示例 13.1 中,left 使用 std::string 类型的键来访问容器,而 right 使用 int 类型的键。

除了支持使用左侧或右侧容器访问单个记录外,boost::bimap 还允许您将记录视为关系(参见示例 13.2)。

示例 13.2。访问关系

#include <boost/bimap.hpp>
#include <string>
#include <iostream>
int main()
{
  typedef boost::bimap<std::string, int> bimap;
  bimap animals;
  animals.insert({"cat", 4});
  animals.insert({"shark", 0});
  animals.insert({"spider", 8});
  for (auto it = animals.begin(); it != animals.end(); ++it)
    std::cout << it->left << " has " << it->right << " legs\n";
}

不必使用左或右访问记录。通过迭代记录,单个记录的左右部分可通过迭代器获得。

虽然 std::map 附带一个名为 std::multimap 的容器,它可以使用相同的键存储多条记录,但 boost::bimap 没有这样的等价物。但是,这并不意味着在 boost::bimap 类型的容器中存储具有相同键的多条记录是不可能的。严格来说,两个必需的模板参数指定左和右的容器类型,而不是要存储的元素的类型。如果未指定容器类型,则默认使用容器类型 boost::bimaps::set_of。此容器与 std::map 一样,仅接受具有唯一键的记录。

示例 13.3。显式使用 boost::bimaps::set_of

#include <boost/bimap.hpp>
#include <string>
#include <iostream>
int main()
{
  typedef boost::bimap<boost::bimaps::set_of<std::string>,
    boost::bimaps::set_of<int>> bimap;
  bimap animals;
  animals.insert({"cat", 4});
  animals.insert({"shark", 0});
  animals.insert({"spider", 8});
  std::cout << animals.left.count("spider") << '\n';
  std::cout << animals.right.count(8) << '\n';
}

示例 13.3 指定了 boost::bimaps::set_of。

除了 boost::bimaps::set_of 之外的其他容器类型可用于自定义 boost::bimap。

示例 13.4。使用 boost::bimaps::multiset_of 允许重复

#include <boost/bimap.hpp>
#include <boost/bimap/multiset_of.hpp>
#include <string>
#include <iostream>
int main()
{
  typedef boost::bimap<boost::bimaps::set_of<std::string>,
    boost::bimaps::multiset_of<int>> bimap;
  bimap animals;
  animals.insert({"cat", 4});
  animals.insert({"shark", 0});
  animals.insert({"dog", 4});
  std::cout << animals.left.count("dog") << '\n';
  std::cout << animals.right.count(4) << '\n';
}

Example13.4

示例 13.4 使用容器类型 boost::bimaps::multiset_of,它在 boost/bimap/multiset_of.hpp 中定义。它的工作方式类似于 boost::bimaps::set_of,除了键不需要是唯一的。示例 13.4 将在搜索有四条腿的动物时成功显示 2。

因为 boost::bimaps::set_of 默认用于 boost::bimap 类型的容器,所以不需要显式包含头文件 boost/bimap/set_of.hpp。但是,当使用其他容器类型时,必须包含相应的头文件。

除了上面显示的类之外,Boost.Bimap 还提供以下类:boost::bimaps::unordered_set_of、boost::bimaps::unordered_multiset_of、boost::bimaps::list_of、boost::bimaps::vector_of 和 boost: :bimaps::unconstrained_set_of。除了 boost::bimaps::unconstrained_set_of,所有其他容器类型都像标准库中的对应容器一样运行。

示例 13.5。使用 boost::bimaps::unconstrained_set_of 禁用一侧

#include <boost/bimap.hpp>
#include <boost/bimap/unconstrained_set_of.hpp>
#include <boost/bimap/support/lambda.hpp>
#include <string>
#include <iostream>
int main()
{
  typedef boost::bimap<std::string,
    boost::bimaps::unconstrained_set_of<int>> bimap;
  bimap animals;
  animals.insert({"cat", 4});
  animals.insert({"shark", 0});
  animals.insert({"spider", 8});
  auto it = animals.left.find("cat");
  animals.left.modify_key(it, boost::bimaps::_key = "dog");
  std::cout << it->first << '\n';
}

boost::bimaps::unconstrained_set_of 可用于禁用 boost::bimap 的一侧。在示例 13.5 中,boost::bimap 的行为类似于 std::map。您无法访问通过腿搜索动物的权利。

示例 13.5 说明了为什么首选 boost::bimap 而不是 std::map 的另一个原因。由于 Boost.Bimap 基于 Boost.MultiIndex,因此 Boost.MultiIndex 的成员函数可用。示例 13.5 使用 modify_key() 修改密钥——这是 std::map 无法实现的。

注意密钥是如何修改的。使用 boost::bimaps::_key 为当前键分配一个新值,这是一个在 boost/bimap/support/lambda.hpp 中定义的占位符。

boost/bimap/support/lambda.hpp 还定义了 boost::bimaps::_data。调用成员函数 modify_data() 时,boost::bimaps::_data 可用于修改 boost::bimap 类型容器中的值。

练习

使用 Boost.Bimap 实现类animals_container:

#include <boost/optional.hpp>
#include <string>
#include <vector>
#include <iostream>
struct animal
{
    std::string name;
    int legs;
    animal(std::string n, int l) : name(n), legs(l) {}
};
class animals_container
{
public:
    void add(animal a)
    {
        // TODO: Implement this member function.
    }
    boost::optional<animal> find_by_name(const std::string &name) const
    {
        // TODO: Implement this member function.
        return {};
    }
    std::vector<animal> find_by_legs(int from, int to) const
    {
        // TODO: Implement this member function.
        return {};
    }
};
int main()
{
    animals_container animals;
    animals.add({ "cat", 4 });
    animals.add({ "ant", 6 });
    animals.add({ "spider", 8 });
    animals.add({ "shark", 0 });
    auto shark = animals.find_by_name("shark");
    if (shark)
        std::cout << "shark has " << shark->legs << " legs\n";
    auto animals_with_4_to_6_legs = animals.find_by_legs(4, 7);
    for (auto animal : animals_with_4_to_6_legs)
        std::cout << animal.name << " has " << animal.legs << " legs\n";
}

到此这篇关于C++ Boost Bimap示例详细讲解的文章就介绍到这了,更多相关C++ Boost Bimap内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解C语言内核字符串转换方法

    详解C语言内核字符串转换方法

    在内核开发模式下,初始化字符串也需要调用专用的初始化函数,如下分别初始化ANSI和UNCODE字符串,本文我们就来看看代码是如何实现的
    2022-09-09
  • 约瑟夫经典问题扩展成双向约瑟夫问题

    约瑟夫经典问题扩展成双向约瑟夫问题

    今天小编就为大家分享一篇关于约瑟夫经典问题扩展成双向约瑟夫问题,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • 浅谈c++性能测试工具之计算时间复杂度

    浅谈c++性能测试工具之计算时间复杂度

    有时候除了测量算法的具体性能指数,我们也会希望测试出算法的时间复杂度,以便我们对待测试的算法的性能有一个更加直观的了解。本文将介绍c++性能测试工具之计算时间复杂度。
    2021-06-06
  • 关于C++静态数据成员的实现讲解

    关于C++静态数据成员的实现讲解

    今天小编就为大家分享一篇关于关于C++静态数据成员的实现讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • String底层函数的实现方式详解

    String底层函数的实现方式详解

    这篇文章主要介绍了String底层函数的实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • C++实现归并排序算法

    C++实现归并排序算法

    这篇文章主要为大家详细介绍了C++实现归并排序算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • C++基于easyx图形库实现打砖块游戏

    C++基于easyx图形库实现打砖块游戏

    这篇文章主要为大家详细介绍了C++基于easyx图形库实现打砖块游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • C++ STL中的常用遍历算法分享

    C++ STL中的常用遍历算法分享

    这篇文章主要为大家详细介绍了C++ STL中两个常用的遍历算法,文中的示例代码讲解详细,具有一定的学习与借鉴价值,感兴趣的小伙伴可以参考一下
    2022-12-12
  • 详解C++ 拷贝构造函数和赋值运算符

    详解C++ 拷贝构造函数和赋值运算符

    本文主要介绍了拷贝构造函数和赋值运算符的区别,以及在什么时候调用拷贝构造函数、什么情况下调用赋值运算符。最后,简单的分析了下深拷贝和浅拷贝的问题。有需要的朋友可以看下
    2016-12-12
  • C++17中std::string_view的使用

    C++17中std::string_view的使用

    std::string_view是C++17标准库中的一种新类型,它提供了对一个字符序列的非拥有式视图,本文主要介绍了C++17中std::string_view的使用,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01

最新评论