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_*::value
为 false
。
在没有可变参数模板支持的编译器中,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_by
、tag
和 composite_key
接受可变数量的参数,其最大数量受内部宏限制。即使是不使用的参数也会影响最终类型,因此手动调整相应的宏可以适度减少符号名称。
类模板 | 限制宏 | 默认值 |
---|---|---|
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 复制)