Skip to content

Trouble composing filtered with reverse graph #462

@andrea-cassioli-maersk

Description

@andrea-cassioli-maersk

I need to run some algorithm on the reverse of a filtered graph.

Moreover I have implemented a graph class FG that inherits from a filtered_graph, mainly for the purpose of exposing some types and add some few other things. But overall a plain inheritance.

Combining FG with a reverse_graph does not seem to work. Here a minimal example


#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/reverse_graph.hpp>


template <typename G, typename F>
class FG : public boost::filtered_graph<G, F> {
 public:
  FG(const G& graph, F f)
      : boost::filtered_graph<G, F>(graph, f) {}
};

template <typename G, typename F>
auto GetFG(const G& graph, F f) {
  return FG<G, F>(graph, f);
}

int main() {
  using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, int, int>;

  const Graph graph;
  const auto filtered = GetFG(graph, [](const auto&) { return true; });
  const auto reverse  = boost::make_reverse_graph(filtered);
  auto [eb, ee] = boost::edges(reverse);
  auto e        = *eb;

  if (const auto prop = reverse[e]; prop > 0) {
    throw std::logic_error("");
  }
}

Compiling with clang I get

/Users/andrea.cassioli/.conan2/p/b/boost6b6b51639ca5b/p/include/boost/graph/graph_traits.hpp:334:25: error: no type named 'edge_bundled' in 'FG<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, int, int>, (lambda at /Users/andrea.cassioli/workspace/DST-Network-Design/test/benchmark/sandbox/benchmark_main.cpp:43:38)>'
  334 |     typedef typename G::edge_bundled type;
      |             ~~~~~~~~~~~~^~~~~~~~~~~~
/Users/andrea.cassioli/.conan2/p/b/boost6b6b51639ca5b/p/include/boost/graph/graph_traits.hpp:349:30: note: in instantiation of template class 'boost::edge_bundle_type<FG<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, int, int>, (lambda at /Users/andrea.cassioli/workspace/DST-Network-Design/test/benchmark/sandbox/benchmark_main.cpp:43:38)>>' requested here
  349 |             typedef typename bundler::type type;
      |                              ^
/Users/andrea.cassioli/.conan2/p/b/boost6b6b51639ca5b/p/include/boost/graph/reverse_graph.hpp:219:29: note: in instantiation of template class 'boost::graph::detail::bundled_result<FG<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, int, int>, (lambda at /Users/andrea.cassioli/workspace/DST-Network-Design/test/benchmark/sandbox/benchmark_main.cpp:43:38)>, boost::detail::edge_desc_impl<boost::directed_tag, unsigned long>>' requested here
  219 |     typename graph::detail::bundled_result< BidirectionalGraph,
      |                             ^
/Users/andrea.cassioli/workspace/DST-Network-Design/test/benchmark/sandbox/benchmark_main.cpp:60:32: note: while substituting deduced template arguments into function template 'operator[]' [with Descriptor = reference]
   60 |   if (const auto prop = reverse[e]; prop > 0) {
      |                                ^
/Users/andrea.cassioli/workspace/DST-Network-Design/test/benchmark/sandbox/benchmark_main.cpp:60:32: error: no viable overloaded operator[] for type 'const reverse_graph<FG<adjacency_list<vecS, vecS, directedS, int, int, no_property, listS>, (lambda at /Users/andrea.cassioli/workspace/DST-Network-Design/test/benchmark/sandbox/benchmark_main.cpp:43:38)>>'
   60 |   if (const auto prop = reverse[e]; prop > 0) {
      |                         ~~~~~~~^~
/Users/andrea.cassioli/.conan2/p/b/boost6b6b51639ca5b/p/include/boost/graph/reverse_graph.hpp:212:5: note: candidate function template not viable: 'this' argument has type 'const reverse_graph<FG<adjacency_list<vecS, vecS, directedS, int, int, no_property, listS>, (lambda at /Users/andrea.cassioli/workspace/DST-Network-Design/test/benchmark/sandbox/benchmark_main.cpp:43:38)>>', but method is not marked const
  212 |     operator[](Descriptor x)
      |     ^
/Users/andrea.cassioli/.conan2/p/b/boost6b6b51639ca5b/p/include/boost/graph/reverse_graph.hpp:222:5: note: candidate template ignored: substitution failure [with Descriptor = reference]
  222 |     operator[](Descriptor x) const
      |     ^

Moreover

  • Using the plain filtered_graph works.
  • Reversing first, filtering then also works.

I am quite puzzle by why my code does not.

I would expect FG to be basically equivalent to filtered_graph.

Any clue? Is it some known limitation? I cannot see anything in the log suggesting

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions