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 |
|---|---|
|
The mutable property-map type returned by |
|
The read-only property-map type returned by |
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
-
Property Maps — the user-facing guide to choosing, constructing, and passing property maps.
-
External Properties — when you want to keep the data outside the graph.
-
property<Tag, T, Next>— the legacy interior property declaration.