Unqualified namespace call function

After looking at the source code of boost::polygon , I saw many applications of the following topic:

 #include <iostream> namespace B { struct A { void foo() const { std::cout << "foo" << std::endl; } }; void bar(const A &a) { a.foo(); } void baz() { std::cout << "baz" << std::endl; } } int main(int argc, char **argv) { B::A a; bar(a); B::baz(); // simply calling baz() does not work return 0; } 

How can bar(a) be called without additional qualifications? I would expect only B::bar(a) to compile.

If the function has no argument inside the namespace, this does not happen.

+7
c ++ namespaces c ++ 11
source share
1 answer

According to ISO C ++ 14, in ยง3.4.2:

When the postfix expression in the function call is unqualified-id, other namespaces that are not taken into account during the usual unqualified search can be found, and in these namespaces, the function of the name or namespace of the namespace, in other words, the visible one can be found. These changes to the search depend on the types of arguments (and for template template arguments, template argument namespace).

And further:

For each type of argument T, in a function call, there is a set of zero or more related namespaces and a set of zero or more related classes that must be considered. The sets of namespaces and classes are completely determined by the types of function arguments.

If T is a class type (including unions), its associated classes: the class itself; the class of which he is a member, if any; and its direct and indirect base classes. Associated namespaces are the innermost encompassing namespaces of related classes .

In fact, you can even prevent this by including a function name:

 (bar)(a); // doens't compile 

but

 (B::bar)(a); // does compile 

Remember also that this applies only to the innermost namespace, which means that in the following situation you need to define a namespace:

 namespace B { namespace C { struct A {}; } void bar(const C::A& a) { ... } } 
+6
source share

All Articles