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;
然后,例如,类型 employee_set::nth_index<0>::type
在 GCC 中解析为以下内容
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
定义为 indexed_by<...>
的派生 struct
,而是将其定义为 typedef
,则类型隐藏将不起作用:typedef
是语法别名,通常在编译器进行任何进一步的类型处理之前会被扩展。
类型隐藏技术也可以应用于 composite_key
实例化,这通常会对符号名称长度产生很大影响。
Boost.MultiIndex 对旧版编译器的支持并未得到积极维护,因此如果您碰巧使用旧环境,则可能需要使用该库的早期版本。下表提供了一些旧版编译器以及已知可与其配合使用的最新版 Boost.MultiIndex(通常具有相应编译器细节部分中所述的限制。)如果您成功地将其中一个与比此处所述更新版本的 Boost.MultiIndex 配合使用,请报告回来,以便更新信息。
编译器 | 已知的最新 兼容版本 |
日期 |
---|---|---|
Borland C++ Builder 6.4 至 2006,CodeGear C++Builder 2010 | 从未与 Boost.MultiIndex 兼容 | |
适用于 Windows 的 Comeau C/C++ 4.3.10.1(VC++ 9.0 后端) | Boost 1.38 | 2009 年 2 月 |
适用于 Tru64 UNIX 的 Compaq C++ 6.5-042 至 7.1-006 | Boost 1.38 | 2009 年 2 月 |
GCC 3.2 至 3.4 | Boost 1.41 | 2009 年 11 月 |
适用于 HP-UX IA64 的 HP aC++ A.06.12 至 A.06.17 | Boost 1.38 | 2009 年 2 月 |
适用于 HP-UX PA-RISC 的 HP aC++ A.03.80 至 A.03.85 | Boost 1.38 | 2009 年 2 月 |
适用于 AIX 的 IBM VisualAge C++ V6.0 | Boost 1.33.1 | 2006 年 12 月 |
适用于 AIX 的 IBM XL C/C++ V9.0 至 V10.1 | Boost 1.41 | 2009 年 11 月 |
适用于 Linux 的 Intel C++ 编译器 8.1 至 11.1 | Boost 1.41 | 2009 年 11 月 |
适用于 Mac OS 的 Intel C++ 编译器 9.1 至 11.0 | Boost 1.41 | 2009 年 11 月 |
适用于 Windows 32 位的 Intel C++ 编译器 8.0 至 11.1 | Boost 1.41 | 2009 年 11 月 |
适用于 Windows 64 位的 Intel C++ 编译器 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 月 |
适用于 Solaris 的 Sun Studio 10 至 12 Update 1 | 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)