Boost 属性映射库主要由概念形式的接口规范组成(类似于 STL 中的迭代器概念 [2])。这些接口规范旨在供通用库的实现者使用,用于向用户传达模板参数的要求。特别是,Boost 属性映射概念定义了一个通用接口,用于将键对象映射到对应的值对象,从而隐藏映射实现的细节,使其与算法无关。满足属性映射接口的类型的实现由算法的客户端提供。属性映射要求对键和值对象的类型故意含糊不清,以便在通用库的函数模板中实现最大的通用性。
对属性映射接口的需求来自 Boost 图形库 (BGL),其中包含许多使用属性映射概念指定其接口的算法示例。例如,请注意ColorMap breadth_first_search 的模板参数。此外,BGL 包含许多实现属性映射接口的具体类型示例。 adjacency_list 类实现了用于访问附加到图形顶点和边的对象(属性)的属性映射。
Boost 属性映射库还包含一些 适配器,这些适配器可以转换常用数据结构(这些数据结构实现映射操作,例如内置数组(指针)、迭代器和 std::map),使其具有属性映射接口。这些适配器并非旨在满足所有映射需求,而是旨在作为如何实现接口以及涵盖一些常见案例的示例。有关详细信息,请参见头文件。
属性映射是静态类型的实体。如果您需要在更动态的环境中访问属性映射(例如,因为您正在从文件中读取一组未知的属性),可以使用 dynamic_properties
类通过动态类型接口访问一组属性映射。
#include <iostream> #include <map> #include <string> #include <boost/property_map/property_map.hpp> template <typename AddressMap> void foo(AddressMap address) { typedef typename boost::property_traits<AddressMap>::value_type value_type; typedef typename boost::property_traits<AddressMap>::key_type key_type; value_type old_address, new_address; key_type fred = "Fred"; old_address = get(address, fred); new_address = "384 Fitzpatrick Street"; put(address, fred, new_address); key_type joe = "Joe"; value_type& joes_address = address[joe]; joes_address = "325 Cushing Avenue"; } int main() { std::map<std::string, std::string> name2address; boost::associative_property_map< std::map<std::string, std::string> > address_map(name2address); name2address.insert(make_pair(std::string("Fred"), std::string("710 West 13th Street"))); name2address.insert(make_pair(std::string("Joe"), std::string("710 West 13th Street"))); foo(address_map); for (std::map<std::string, std::string>::iterator i = name2address.begin(); i != name2address.end(); ++i) std::cout << i->first << ": " << i->second << "\n"; return EXIT_SUCCESS; }
对于每个属性映射对象,都有一组为其定义了到值对象的映射的有效键。对无效键调用属性映射函数会导致未定义的行为。属性映射概念未指定如何创建或修改此有效键集。使用属性映射的函数必须在其前提条件中指定预期的有效键集。
对属性映射的需求源于 Boost 图形库的设计,其算法需要一个接口来访问附加到图形中顶点和边的属性。在这种情况下,顶点和边描述符是属性映射的键类型。
几类属性映射提供了不同的访问功能
为这四类属性映射中的每一类都定义了一个单独的概念。这些属性映射概念列在下面,并附有每个概念的文档链接。
每个类别的属性映射都有一个标签结构,它在头文件中定义<boost/property_map/property_map.hpp>.
namespace boost { struct readable_property_map_tag { }; struct writable_property_map_tag { }; struct read_write_property_map_tag : public readable_property_map_tag, public writable_property_map_tag { }; struct lvalue_property_map_tag : public read_write_property_map_tag { }; }
类似于std::iterator_traitsSTL 类,有一个boost::property_traits类可用于推断与属性映射类型关联的类型:键和值类型以及属性映射类别。有一个特化boost::property_traits以便指针可以用作属性映射对象。此外,属性映射函数是为指针重载的。这些特性类和函数在<boost/property_map/property_map.hpp>.
namespace boost { template <typename PropertyMap> struct property_traits { typedef typename PropertyMap::key_type key_type; typedef typename PropertyMap::value_type value_type; typedef typename PropertyMap::reference reference; typedef typename PropertyMap::category category; }; }
namespace boost { // specialization for using pointers as property maps template <typename T> struct property_traits<T*> { typedef T value_type; typedef T& reference; typedef std::ptrdiff_t key_type; typedef random_access_iterator_pa_tag category; }; // overloads of the property map functions for pointers template<> void put(T* pmap, std::ptrdiff_t k, const T& val) { pmap[k] = val; } template<> const T& get(const T* pmap, std::ptrdiff_t k) { return pmap[k]; } }
版权所有 © 2000-2002 | Jeremy Siek,印第安纳大学 ([email protected]) |