Loads of C++ libraries, the standard included, allow you to adapt your objects for use in the libraries. The choice is often between a member function or a free function in the same namespace.
I'd like to know mechanics and constructs the library code uses to dispatch a call which will call one of these "extension" functions, I know this decision has to take place during compile time and involves templates. The following runtime psuedocode is not possible/non-sense, the reasons are out of the scope of this question.
if Class A has member function with signature FunctionSignature
choose &A.functionSignature(...)
else if NamespaceOfClassA has free function freeFunctionSignature
choose freeFunctionSignature(...)
else
throw "no valid extension function was provided"
The code above looks like runtime code :/. So, how does the library figure out the namespace a class is in, how does it detect the three conditions, what other pitfalls are there that need to be avoided.
The motivation for my question is for me to be able to find the dispatch blocks in libraries, and to be able to use the constructs in my own code. So, detailed answers will help.
!!TO WIN BOUNTY!!
Ok so according to the answer from Steve (and the comments) ADL and SFINAE are the key constructs for wiring up the dispatch at compile time. I've got my head arround ADL (primitively) and SFINAE (again rudementary). But I don't know how they orchistrate together in the way I think they should.
I want to see a illustrative example of how these two constructs can be put together so that a library can choose at compile time whether to call a user supplied member function in an object, or a user supplied free function supplied in the same object's namespace. This should only be done using the two constructs above, no runtime dispatch of any sort.
Lets say the object in question is called NS::Car
, and this object needs to provide the behaviour of MoveForward(int units)
, as a member function ofc. If the behaviour is to be picked up from the object's namespace it will probably look like MoveForward(const Car & car_, int units)
. Lets define the function that wants to dispatch mover(NS::direction d, const NS::vehicle & v_)
, where direction is an enum, and v_ is a base class of NS::car
.