You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何借助Boost Property Maps为二叉树启用方括号运算符语法?

问题描述

目标是在二叉树类中加入property maps,实现符合BGL风格的顶点属性访问语法:

using vertex_properties = std::string;
using tree_type = binary_tree<vertex_properties, boost::no_property>;
using vertex_descriptor = tree_type::vertex_descriptor;
tree_type tree;
vertex_descriptor a = add_vertex(tree, "a");
vertex_descriptor b = add_vertex(tree, "b");
assert(tree[a] == "a");
tree[a] = tree[b];
assert(tree[a] == "b");

已实现add_vertex函数,但无法启用方括号运算符语法。尝试在tree_type类中定义VertexManager类实例:

template<typename Graph, typename VertexProperty>
struct VertexManager
{
    using vertex_descriptor = typename Graph::vertex_descriptor;
    using vertex_hashmap_type = std::map<vertex_descriptor, VertexProperty>;
    vertex_hashmap_type _vertex_property_hashmap;
    boost::associative_property_map< vertex_hashmap_type > _vertex_property_map { _vertex_property_hashmap };

    template<typename... Args>
    vertex_descriptor add_vertex_to_manager(Graph &g, Args&&... args)
    {
        vertex_descriptor key = add_vertex(g);
        VertexProperty value = { std::forward<Args>(args)...};
        put(_vertex_property_map, key, value);
        return key;
    }

    const VertexProperty& operator [](vertex_descriptor v) const
    {
        return get(_vertex_property_hashmap, v);
    }

    VertexProperty & operator [](vertex_descriptor v)
    {
        return get(_vertex_property_hashmap, v);
    }
};

但该方案无效,原因是Boost的get函数匹配到了const接口重载:

template <class T>
inline const T& get(const T* pa, std::ptrdiff_t k) { return pa[k]; }

需要找到获取map中元素原位引用的方法。

解决方案

问题出在你直接对std::map调用get,这会匹配到Boost中针对数组的get重载,而非针对property map的版本。你有两种可行的修正方式:

方式一:直接操作std::map

既然add_vertex_to_manager已经确保顶点描述符对应的属性存在于map中,你可以直接使用std::map的at()方法来获取引用,该方法在const和非const实例下分别返回const和非const引用:

const VertexProperty& operator [](vertex_descriptor v) const
{
    return _vertex_property_hashmap.at(v);
}

VertexProperty & operator [](vertex_descriptor v)
{
    return _vertex_property_hashmap.at(v);
}

at()方法在键不存在时会抛出std::out_of_range异常,这符合BGL中访问无效顶点属性的错误语义。

方式二:使用Boost associative_property_map的get重载

如果你想坚持使用BGL的property map机制,需要显式调用针对boost::associative_property_map的get重载,而非直接操作原始map:

const VertexProperty& operator [](vertex_descriptor v) const
{
    return boost::get(_vertex_property_map, v);
}

VertexProperty & operator [](vertex_descriptor v)
{
    return boost::get(_vertex_property_map, v);
}

这里必须显式指定boost::get,避免编译器匹配到其他无关的get重载。boost::associative_property_map的get方法会根据自身的const属性返回对应的引用类型。

额外注意

确保你的vertex_descriptor类型可以作为std::map的键(即支持<比较运算符),这是std::map的要求,也是BGL顶点描述符的常规约定。

内容的提问来源于stack exchange,提问作者WaterFox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 02:20:22