On Saturday, December 22, 2012 18:35:47 Walter Bright wrote: > On 12/22/2012 8:03 AM, Andrei Alexandrescu wrote: > > I think this is a fallacious argument because it concludes that apples > > should be peeled because oranges should. > > Given, in C++: > > struct S > { > public: > void foo(int); > private: > void foo(float); > } > > void bar() > { > S s; > s.foo(1.0f); > } > > This is an error in C++: > > foo.cpp:6: error: âvoid S::foo(float)â is private > > (I used g++ so nobody would complain this is a defect in dmc++.) > > Why does this never come up on peoples' complaints about C++? I spent some > time googling it, and came up with nothing. > > I don't think it can be dismissed as fallacious unless the why's have a > rationale.
Probably because both functions are in the same place, and C++ is far less picky about implicit conversions, meaning that it's _much_ more likely to simply select the public function rather than complain about a conflict (though as your code demonstrates, such a conflict is still possible). Contrast this with D where the compiler is extremely quick to give you an error about functions conflicting rather than trying to guess which one you meant. Also, with C++, this is restricted to the class that you're dealing with. Derived classes generally won't have the problem (if they overload foo, it'll just call the derived one IIRC rather than complaining about the private one in the base class). So, any breakage you get is directly related to that class. Whereas in D, simply adding a private function to a module can cause a conflict with a completely different module. Such functions in C++ wouldn't even be visible, because they'd be hidden in the cpp file, so you only get that problem when you add more "public" functions (quotes, since there aren't really any access levels for free functions in C++). In addition, in my experience, it's quite rare for classes to have public and private functions with the same name, meaning that you just don't hit this problem very often. That's probably why it doesn't garner many complaints in C++. Contrast this with D, where with modules, it's trivial to have completely unrelated free functions with the same name which end up conflicting where one is private and another is public. At least with a class, the functions would be related. With modules, the functions are likely to be completely unrelated and much more like to be written by completely different people. I don't think that D programmers generally complain about this with classes, though UFCS will probably increase those complaints. They mostly complain about this with modules - a problem that C++ doesn't have. And it's the module situation which desparately needs to be fixed. But UFCS will make it so that the problem crops up far more with classes as well, since now anyone can effectively add a function to a class, potentially causing conflicts not only with other functions used with UFCS but also causing problems when the class maintainer adds private functions to the class which would conflict. In C++, you can only get a conflict with derived classes, and in general, the overload rules there make it so that it's not a problem if the public function being clashed with is overridden in the derived class. And more of the problems that you do have are less obvious when they happen and are hard to catch due to C++'s greater laxity with implicit conversions and overload selection. So, while C++ has the problem, it's on a much, much smaller scale - hence why you don't see a lot of complaints about it in C++. Whereas in D, it happens rather frequently, so plenty of people complain. So, I really think that we would be far better off to make it so that inaccessible functions are never in overload sets. Carrying overy C++'s behavior in this case is just going to cause us grief. - Jonathan M Davis