C++ Boost Graph: How to customize callback function vf2_print_callback in vf2_subgrap_iso.hpp

boost, c++, callback

Solution

Two issues:

bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1) {

    BGL_FORALL_VERTICES_T(v, graph1_, Graph1)
        vertex_iso_map.push_back(std::make_pair( get(boost::vertex_index_t(), graph1_, v) , get(boost::vertex_index_t(), graph2_, get(f, v))));
        set_of_vertex_iso_map.push_back(vertex_iso_map);
        vertex_iso_map.clear();

    return true;
}

At least fix the formatting to express the intent:

bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1) {

    BGL_FORALL_VERTICES_T(v, graph1_, Graph1) {
        vertex_iso_map.emplace_back(get(boost::vertex_index_t(), graph1_, v), get(boost::vertex_index_t(), graph2_, get(f, v)));
    }
    set_of_vertex_iso_map.push_back(vertex_iso_map);
    vertex_iso_map.clear();

    return true;
}

And the real issue is:

boost::vf2_subgraph_iso(graph_small, graph_large, callback);

Passes `callback` by value, acting on copies! Pass by reference:

boost::vf2_subgraph_iso(graph_small, graph_large, std::ref(callback));

Problem

Background: I am using `boost::vf2_subgraph_iso(graph1, graph2, callback)` in vf2_sub_graph_iso.hpp. In sample provided by `boost`, they used `boost::vf2_print_callback<graph_type, graph_type> callback(graph1, graph2)` to print vertex pair to terminal. What I've done: I want to customize the callback function so that once `boost::vf2_subgraph_iso(graph1, graph2, callback)` called it will make a call to my callback function. The reason I want to customize callback function is that I want to store vertex pair in vector rather than printing them in terminal. Below is my work so far: ``` #include <utility> #include <vector> #include <fstream> #include <boost/graph/adjacency_list.hpp> #include <boost/graph/vf2_sub_graph_iso.hpp> #include <boost/graph/graphviz.hpp> template <typename Graph1, typename Graph2> class my_call_back { public: // constructor my_call_back(const Graph1& graph1, const Graph2& graph2) : graph1_(graph1), graph2_(graph2) {} template <typename CorrespondenceMap1To2, typename CorrespondenceMap2To1> bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1) { BGL_FORALL_VERTICES_T(v, graph1_, Graph1) vertex_iso_map.push_back(std::make_pair( get(boost::vertex_index_t(), graph1_, v) , get(boost::vertex_index_t(), graph2_, get(f, v)))); set_of_vertex_iso_map.push_back(vertex_iso_map); vertex_iso_map.clear(); return true; } std::vector <std::vector <std::pair<int, int>>> get_setvmap() { return set_of_vertex_iso_map; } private: const Graph1& graph1_; const Graph2& graph2_; std::vector <std::vector <std::pair<int, int>>> set_of_vertex_iso_map; std::vector <std::pair<int, int>> vertex_iso_map; }; int main() { typedef boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS> GraphType; std::ifstream dot_small("small.dot"); std::ifstream dot_large("large.dot"); std::ofstream subgraph_iso_output("large1.dot"); GraphType graph_small, graph_large; boost::dynamic_properties dp(boost::ignore_other_properties); boost::read_graphviz(dot_small, graph_small, dp); boost::read_graphviz(dot_large, graph_large, dp); my_call_back<GraphType, GraphType> callback(graph_small, graph_large); boost::vf2_subgraph_iso(graph_small, graph_large, callback); // get vector from callback auto set_of_vertex_iso_map = callback.get_setvmap(); // output vector size here std::cout << set_of_vertex_iso_map.size() << std::endl; for (auto set_of_v : set_of_vertex_iso_map) { for (auto v : set_of_v) std::cout << "(" << v.first << ", " << v.second << ")" << " "; std::cout << std::endl; } boost::write_graphviz(subgraph_iso_output, graph_small); return 0; } ``` My Problem: After calling `boost::vf2_subgraph_iso` function, I decide to get vector from object `callback`. But it seems like the vector is always empty. I think there is something to do with `BGL_FORALL_VERTICES_T` macro defined in iteration_macros.hpp, but when I look at it I can't find any clue. I was guessing: Maybe callback called by `vf2_subgraph_iso` function makes new `my_callback` object and destroy it when function is done. But how can the function makes new `my_callback` object? I don't understand. And how can I fix it? (Right now I can only set vector as global variable to make it work, which is a horrible choice)

Original source