1. A hidden private function must not have the same name as any other member function.
2. A hidden private function is only part of the overload set when the call site is in another member function of the same class, and its declaration has been seen (as if it had been a global function).
It may be required to state clearly again that this proposal does not offer any way to break the private protection as these new functions are only callable from other member functions. So while anyone can write one you'd have to change the source code of a non-private member function. If you can do that, well, then you don't need a hidden private function to access the private data members...
Hi,
Wondering if modules shouldn't solve the problem?
If it is not the case, I'm not sure we need some
syntactic sugar, given we have the suggested and well known
private friend class idiom.
In the following example we have in comments what can be done now and with a // ** one possibility for the syntactical sugar version could be.
It uses a variation of the suggested private
friend class idiom in this thread
> 1. A hidden private function must not have the same name as any other member function.Unfortunately, we will also need to ensure that its name is different from any other function in all the accessible global and namespace scopes, including those that are introduced after the hidden private function in a given translation unit. And there is no way to force a particular name resolution should the programmer want to.
> 2. A hidden private function is only part of the overload set when the call site is in another member function of the same class, and its declaration has been seen (as if it had been a global function).I do not think how this changes anything. It is the other member functions where we need name lookup to be unambiguous, because non-members cannot access private functions anyway. So restricting overload resolution to just member functions achieves nothing. Perhaps I misunderstood what you said.
But your response got me thinking, and I have a modified proposal.The hidden private members shall only be resolvable via a specially qualified name: private::name, where private is the keyword and name is the name of a hidden private member. They are otherwise not part of the name lookup process.
Thus, hidden private members are only accessible to members and friends, and only when those explicitly want to use them.
Cheers,V.
My concern is not that the hidden private members can be defined in a rogue cpp file and somehow break encapsulation. As I stated in the original message, they are only callable by members (and friends), so that's not a concern at all. I have not tried to address that again in follow-up messages.
What I did try to address is the situation when one translation unit defines hidden private members, while another does not; moreover, let's postulate that when they are defined they hide some global functions, or they overload some other members. Then the lookup for those names (unless modified per my second proposal) will work differently between those two TUs, potentially breaking the program silently.
Different name lookup, while possible for non-member function even today, is not possible for member functions. The latter is a strong and useful guarantee afforded by member functions, breaking it would be very bad. Worse still, this can even break currently valid code, which knows nothing about hidden private members. I'm pretty sure this cannot ever pass through the committee.
Note also that hidden member functions could, in principle, be injected by a rogue include file, even though I believe it is far more likely to happen through error rather than malice.
Which is why I think that the opt-in through private:: is necessary. Yes, this makes things a little more verbose than I would have liked; but this is balanced by not having to decorate "implementation details" in some other way, which is frequently the case in the real-world code.