c++boostnamespacesboost-graphargument-dependent-lookup

Why does "xxx::function();" not work but "using namespace xxx; function();" does?


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?


Solution

  • 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.