3

I am using Boost's graph C++ library, and I stumbled over a problem when asking for the number of vertices of a grid graph.

The following code snipped creates a 2-dimensional grid graph of shape 5 by 6, and then prints the number of vertices of that graph, which is 5x6 = 30. However, this does not compile with the error:

error: ‘num_vertices’ is not a member of ‘boost’

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

int main()
{
    typedef boost::grid_graph<2> Graph;
    Graph g({5, 6});
    std::cout << "Num vertices: " << boost::num_vertices(g) << std::endl;

    return 0;
}

If I change the code to include using namespace boost; at the beginning, then it does work:

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

using namespace boost;

int main()
{
    typedef grid_graph<2> Graph;
    Graph g({5, 6});
    std::cout << "Num vertices: " << num_vertices(g) << std::endl;

    return 0;
}

Curiously, this is not a problem when I use a different Boost graph type, like boost::adjacency_list<>.

So I have three questions:

  1. Which operating principle of namespaces causes this behavior?

  2. Regarding the special case of the grid graph implementation in Boost: Is this a bug or is this intended behavior?

  3. Is there any way I can call the num_vertices function without the using directive?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
badboul
  • 41
  • 5
  • This doesn't address the question, but nothing in either of those code examples needs the extra stuff that `std::endl` does. `'\n'` ends a line. – Pete Becker Jul 26 '23 at 16:08
  • There is a third option - don't use either `using namespace` or a `boost::` prefix. That lets ADL find the function. A qualified name disables ADL. – BoP Jul 26 '23 at 18:30

1 Answers1

5

According to https://www.boost.org/doc/libs/1_82_0/libs/graph/doc/VertexListGraph.html, this function must be called as num_vertices(g).

It is probably implemented as a "hidden friend function", meaning it can only be found via argument-dependent lookup.

Artyer
  • 31,034
  • 3
  • 47
  • 75
  • That's it. The hidden friend function is a thunk routine that calls the protected member function of the same name. – Eljay Jul 26 '23 at 14:30
  • @Eljay basically. Though calling it a member function van be unnecessarily confusing: it's a friend (ie. static by definition) function declared within the class scope – sehe Jul 26 '23 at 14:56
  • @sehe • The non-member hidden friend function calls a protected member function. – Eljay Jul 26 '23 at 15:20
  • @Eljay typically, not necessarily. Also, that non -static member is not usually by the same name anyways. – sehe Jul 26 '23 at 18:20
  • @sehe • I was referring to this `num_vertices` case in particular. I concur with you, that in the general case there are no requirements like this, no constraints, and no impositions. Not even an informal convention (that I'm aware of). – Eljay Jul 26 '23 at 18:28