Why are class member functions shadow functions of the same name?

I recently learned that member functions completely hide free functions with the same name inside a class. By "full" I mean that every free function with the same name is not considered at all to allow overloading. I can understand why this happened with something like this:

void f(); struct S { void f(); void g() { f(); // calls S::f instead of ::f } }; 

where functions have identical signatures, this is natural since the variable scope works the same way. But why prohibit explicit calls when a free function has a different signature, for example:

 void f(); struct S { void f(int x); void g() { f(); // fails to compile attempting to call S::f, which has wrong signature } }; 

I am not asking how to call a hidden free function inside a class. What I want to know is the rationale for this design.

+10
source share
3 answers

To search for an unqualified name, only one area is considered at a time, and if a search in this area does not produce any results, a search for the next higher area is performed. In your case, only area S is searched.

But why forbid unambiguous calls, where a free function has a different signature:

The problem is that the search for the name does not concern anything except the name, identifier. This does not pay attention to the fact that you want to call the function, it just sees the identifier. The same name lookup happens if you just use auto x = f; , and if you think so, there are very good reasons why you need a very limited search area. Everything else will simply surprise the user.

+7
source

There is a special, very surprising rule (but this does not apply to your example), stating that after searching for a class name by searching by name, namespace areas are not visible:

 #include <string> struct C { std::string s; explicit C (std::string); void swap (C& rhs) { swap (s, rhs.s); // error: swap is C::swap } }; void swap (C& lhs, C& rhs) { swap (lhs.s, rhs.s); // std::swap(string,string) } 

IMO, this is crazy.

But why forbid unambiguous calls, where a free function has a different signature:

The name search occurs before permission is overloaded:

  • If the search is ambiguous, permission overload is not performed.
  • If no viable function is found when searching by name, no other search rounds are checked.

The rules are quite complex without the โ€œfeedbackโ€ between overloading and finding names. I would suggest simplification (for example, removing the namespace name list rule for hidden element names and removing the ambiguous name lookup) rather than complexification.

+3
source

I canโ€™t give an authoritative answer (maybe some remember the quote from Design and Evolution of C++ or were actually on the committee at that time), but my first guess would be to accurately fail when you show. It is easy to forget how many things are available at a particular point in time. In addition, overload resolution can be quite complex, and there may be arguments and default conversion. Therefore, I would prefer that in this case there is a maximally limited area in order to always be sure what exactly is being called.

+2
source

All Articles