Boost C++ 库

...世界上最受尊敬和设计最精良的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

Boost.MultiIndex 编译器特定信息



Boost.MultiIndex 利用了一些 C++11 的功能,但也能够在符合 C++03 标准的环境中良好运行。我们列出了一些可能的限制以及可用的解决方法。

目录

移动语义

Boost.MultiIndex 使用 Boost.Move 来支持没有右值引用的编译器。在这种情况下,为了利用 multi_index_container<Value> 在插入和处理仅可移动元素方面的更高效率,需要对 Value 进行适当的工具化。

分配器感知

在 C++11 之前的编译器或缺乏正确 分配器感知 机制(基本上是 std::allocator_traits)的缺陷环境中,对于所有分配器,Boost.MultiIndex 的行为都如同 std::allocator_traits<allocator_type>::propagate_on_container_*::valuefalse

Emplace 函数

在没有可变参数模板支持的编译器中,Boost.MultiIndex 的 emplace 函数通过接受最多 BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS 个构造参数来模拟此缺失的功能,这些参数在内部通过 Boost.Move 转发:在这种情况下,仅允许常量左值引用和右值作为构造参数。

BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS 默认值为 5,用户可以全局定义为不同的值。

初始化列表

在缺少 std::initializer_list 的情况下,无法提供此功能的透明模拟:可以考虑使用 Boost.Assign 作为可能的替代方案。

元组

在库接口中使用 std::tuple 的任何地方,都可以使用 boost::tuple 来代替。然而,反之则不然。

缩减符号名称长度

multi_index_container 实例化生成的类型通常会产生非常长的符号名称,有时会超出某些编译器的内部限制。有几种技术可以缩短生成的符号名称:这些技术还具有使生成的错误消息更易于阅读的额外好处。

最大参数数量的限制

类模板 indexed_bytagcomposite_key 接受可变数量的参数,其最大数量受内部宏限制。即使是不使用的参数也会影响最终类型,因此手动调整相应的宏可以适度减少符号名称。

限制 Boost.MultiIndex 某些类模板的最大参数数量。
类模板 限制宏 默认值
 indexed_by   BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE  20
 tag   BOOST_MULTI_INDEX_LIMIT_TAG_SIZE  20
 composite_key   BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE  10

类型隐藏

考虑一个典型的 multi_index_container 实例化

typedef multi_index_container<
  employee,
  indexed_by<
    ordered_unique<identity<employee> >,
    ordered_non_unique<member<employee,std::string,&employee::name> >,
    ordered_unique<member<employee,int,&employee::ssnumber> >
  >
> employee_set;

然后,例如,在 GCC 中,类型 employee_set::nth_index<0>::type 解析为以下内容

boost::multi_index::detail::ordered_index<
  boost::multi_index::identity<employee>,
  std::less<employee>,
  boost::multi_index::detail::nth_layer<
    1, employee,
    boost::multi_index::indexed_by<
      boost::multi_index::ordered_unique<
        boost::multi_index::identity<employee>, mpl_::na, mpl_::na
      >,
      boost::multi_index::ordered_non_unique<
        boost::multi_index::member<employee, std::string, &employee::name>,
        mpl_::na, mpl_::na
      >,
      boost::multi_index::ordered_unique<
        boost::multi_index::member<employee, int, &employee::ssnumber>,
        mpl_::na, mpl_::na
      >,
      mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na,
      mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na,
      mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na
    >,
    std::allocator<employee>
  >,
  boost::mpl::vector0<mpl_::na>,
  boost::multi_index::detail::ordered_unique_tag
>

可以看出,类型名称的很大一部分是由 indexed_by<...> 部分贡献的,这仅仅是在 employee_set 的定义中提供的索引指定符列表的扩展版本。我们可以通过将其封装到另一个名称较短的构造中来防止这个非常长的名称出现在最终类型中

// reducing symbol names through type hiding
// type hide the index specifier list within employee_set_indices

struct employee_set_indices:
  indexed_by<
    ordered_unique<identity<employee> >,
    ordered_non_unique<member<employee,std::string,&employee::name> >,
    ordered_unique<member<employee,int,&employee::ssnumber> >
  >
{};

typedef multi_index_container<
  employee,
  employee_set_indices
> employee_set;

employee_set_indices 在所有方面都像传统的 typedef 一样工作,除了一个细节:它的名称没有明确包含 indexed_by 实例化中包含的信息。应用此技术,employee_set::nth_index<0>::type 现在变为

boost::multi_index::detail::ordered_index<
  boost::multi_index::identity<employee>,
  std::less<employee>,
  boost::multi_index::detail::nth_layer<
    1, employee,
    employee_set_indices,
    std::allocator<employee>
  >,
  boost::mpl::vector0<mpl_::na>,
  boost::multi_index::detail::ordered_unique_tag
>

这比原始类型短得多,也更容易被人阅读。如果我们将 employee_set_indices 定义为 typedef,而不是使其成为 indexed_by<...> 的派生 struct,类型隐藏将不起作用:typedef 是语法别名,通常会在编译器进行任何进一步的类型处理之前被展开。

类型隐藏技术也可以应用于 composite_key 实例化,这通常会大大增加符号名称的长度。

旧编译器

Boost.MultiIndex 对旧编译器的支持没有积极维护,因此如果您碰巧在使用旧环境,您可能需要使用库的早期版本。下表提供了一些旧编译器以及已知适用于它们的最新 Boost.MultiIndex 版本(通常在相应的编译器特定信息部分中解释了限制)。如果您成功地在比此处声明的更新版本的 Boost.MultiIndex 上尝试了其中一个,请反馈,以便可以更新信息。

对旧编译器的支持。
编译器 最新已知
兼容版本
日期
Borland C++ Builder 6.4 到 2006, CodeGear C++Builder 2010 从未与 Boost.MultiIndex 一起工作过
Comeau C/C++ 4.3.10.1 for Windows (VC++ 9.0 后端) Boost 1.38 2009年2月
Compaq C++ 6.5-042 到 7.1-006 for Tru64 UNIX Boost 1.38 2009年2月
GCC 3.2 到 3.4 Boost 1.41 2009年11月
HP aC++ A.06.12 到 A.06.17 for HP-UX IA64 Boost 1.38 2009年2月
HP aC++ A.03.80 到 A.03.85 for HP-UX PA-RISC Boost 1.38 2009年2月
IBM VisualAge C++ V6.0 for AIX Boost 1.33.1 2006年12月
IBM XL C/C++ V9.0 到 V10.1 for AIX Boost 1.41 2009年11月
Intel C++ Compiler for Linux 8.1 到 11.1 Boost 1.41 2009年11月
Intel C++ Compiler for Mac OS 9.1 到 11.0 Boost 1.41 2009年11月
Intel C++ Compiler for Windows 32-bit 8.0 到 11.1 Boost 1.41 2009年11月
Intel C++ Compiler for Windows 64-bit 10.0 到 11.11 Boost 1.41 2009年11月
Metrowerks CodeWarrior 8.3 Boost 1.36 2008年8月
Metrowerks CodeWarrior 9 到 9.5 Boost 1.34.1 2007年7月
Microsoft Visual C++ 6.0 Service Pack 5 Boost 1.36 2008年8月
Microsoft Visual C++ 7.0 Boost 1.35 2008年3月
Sun Studio 10 到 12 Update 1 for Solaris Boost 1.41 2009年11月




修订于 2020年1月25日

© 版权所有 2003-2020 Joaquín M López Muñoz。根据 Boost 软件许可协议 1.0 版本分发。(请参阅随附文件 LICENSE_1_0.txt 或在 https://boost.ac.cn/LICENSE_1_0.txt 复制)