C++ has a feature, that in-class-defined friend functions can only be found by ADL (argument dependent lookup):
struct Foo {
friend void fn(Foo) { } // fn can only be called by ADL, it won't be found by other lookup methods
};
Is it possible to achieve the same for non-friend functions? I ask this, because sometimes, I'd like to have this "only found by ADL" feature, but I don't actually need friend access to the class internals.
(And a somewhat opinionated question: if this is not possible, what is the reason for this? Is this "only found by ADL" rule intentionally designed into the language?)
It's only possible for friend functions, since they are the only functions for which this verbiage exists. Both the wording that makes functions invisible to ordinary name lookup, and the wording that considers them during ADL, is applied only to such friends.
This feature was actually introduced to replace another feature, that was deemed more problematic. N0777 is the paper detailing it. Templates used to inject their friend function names into scope when a template was instantiated, to be found by regular name lookup. That wasn't ideal and caused issues in overload resolution.
The feature was set to be removed, but it was the backbone of the Barton-Nackman trick, and so a solution was proposed that ultimately became what we know as inline friend functions being looked up by ADL only. It was tailored to facilitate the programming idiom.
Since no other wide-spread idiom that required such behavior was brought up since, this behavior wasn't extended to non-friend functions.