This documentation is being rewritten. If something looks off, please cross-check with the Boost 1.91.0 Boost.Graph docs and open an issue.

property_map<Graph, PropertyTag>

Maps a (graph type, property tag) pair to the concrete property-map type the graph hands you when you call get(tag, g). Every BGL graph class specializes property_map for the property tags it supports.

Defined in: <boost/graph/properties.hpp>

When to use it

In a function signature. If the graph is passed by mutable reference, you want property_map<G, Tag>::type; if it is passed by const reference, you want property_map<G, Tag>::const_type. Inside function bodies auto is usually fine.

// Mutable graph: ::type works.
auto w = get(edge_weight, g);                                // g is Graph&
property_map<Graph, edge_weight_t>::type same = get(edge_weight, g);

// Const graph: must use ::const_type.
auto w = get(edge_weight, g);                                // g is const Graph&
property_map<Graph, edge_weight_t>::const_type same = get(edge_weight, g);
const_type is not interchangeable with const type. Declare the type as const if you want; do not declare a variable of type const property_map<…>::type — that produces a readable-only wrapper whose template errors are famously cryptic.

Example

// Demonstrates property_map<Graph, Tag>::type vs ::const_type.
//
// Rule of thumb: if your Graph& is const, you get ::const_type; otherwise
// you get ::type. Deducing it via `auto` (C++14) sidesteps the choice
// entirely and is what most code should do.

#include <boost/graph/adjacency_list.hpp>
#include <iostream>

using namespace boost;
using Graph = adjacency_list<vecS, vecS, directedS,
    no_property, property<edge_weight_t, int>>;

// Mutable graph: ::type works.
void print_weights(Graph& g) {
    using PMap = property_map<Graph, edge_weight_t>::type;
    PMap w = get(edge_weight, g);
    for (auto e : make_iterator_range(edges(g))) {
        std::cout << "(" << source(e, g) << "," << target(e, g)
                  << ") weight=" << get(w, e) << '\n';
    }
}

// Const graph: ::const_type is required.
int total_weight(const Graph& g) {
    using PMap = property_map<Graph, edge_weight_t>::const_type;
    PMap w = get(edge_weight, g);
    int total = 0;
    for (auto e : make_iterator_range(edges(g))) total += get(w, e);
    return total;
}

int main() {
    Graph g(3);
    add_edge(0, 1, 5, g);
    add_edge(1, 2, 3, g);
    add_edge(0, 2, 8, g);

    print_weights(g);
    std::cout << "total = " << total_weight(g) << '\n';
}
(0,1) weight=5
(0,2) weight=8
(1,2) weight=3
total = 16

Synopsis

namespace boost {

template <class Graph, class PropertyTag>
struct property_map {
    typedef /* specialized per graph */ type;
    typedef /* specialized per graph */ const_type;
};

} // namespace boost
Nested type Description

type

The mutable property-map type returned by get(tag, g) when g is a non-const graph. Models a ReadWritePropertyMap (or LvaluePropertyMap, depending on the graph).

const_type

The read-only property-map type returned by get(tag, g) when g is a const graph. Models a ReadablePropertyMap.

How specializations are written

A graph type opts into a property tag by specializing property_map:

namespace boost {
template <class Config>
struct property_map<my_graph<Config>, edge_weight_t> {
    typedef /* some concrete map */       type;
    typedef /* some concrete map */ const_type;
};
}

If you are adapting an existing graph library so that BGL algorithms can use it, this is the extension point.

See also