Why in the next program the member function foo has priority over the global foo although the global one match the type?
#include
using name
One of the tenets of method overloading is that the specific should trump the general. In your example, the member method will always be more specific than a global method.
In general, when scopes are nested, any name declared in the inner scope hides any entities with the same name in an outer scope when that name is used in the inner scope. So, in this case, when used in the class scope, names declared in the class will hide those declared in the enclosing namespace.
The outer name is still available if you qualify it; in this case, being in the global namespace, it's available as ::foo
.
You could think of it as increasing "specialisation" as you move from the global namespace through any nested namespaces around your class, nested classes etc. down to the member functions involved. If you say "foo" in this inner context, a more "specialised" foo
can be expected to be more relevant to the caller. Further, if the global one was used preferentially, then someone adding symbols to a less "specialised" scope could break a class that defined a same-named symbol, undoing a lot of the benefits of namespaces and identifier scoping. The basic idea is that your class has a lot of freedom to use meaningful but concise identifiers - which may well be used by other code in your application - but it's only when a meaning for that identifier isn't available in the most local scope that it starts looking further and further afield.
In terms of priority for scope resolution (default) when using same name of an identifier, local scope, member of class (class scope), global scope
Consider what would happen if a global function declared somewhere in your code base (possibly several #include
statements away) would trump an class obj
member function declared right there in the class itself...
It would mean that, if you want to play it safe, you would have to fully qualify every single call to a member function...
this->foo();
...instead of having to qualify the less likely case of actually referring to the global function.
::foo();
This is called the "concept of least surprise".
Because the member function named foo
could be found at the class scope, and then name lookup will stop, so the global version foo
won't be considered for overload resolution, even if the global version is more appropriate here. It is a kind of name hiding.
If you want to call the global version, you could explicitly call it by ::foo(6.4);
.
And here is a workaround to bring the global function into overload resolution.
Reference for Unqualified name lookup