Some implementations have the type of
test.begin() as part of the standard namespace (it could be
char*).
Those implementations will perform argument-dependent lookup, find
std::partition (if it happens to be included, directly
or indirectly, by the user or the implementation), and fail to choose between the two unconstrained candidates.
Very roughly, the process works like this:
1. Name lookup finds all the functions and function templates with a particular name, and produces a list of all the stuff;
2. Template arguments are deduced, if required, then substituted into each function template in the list from step one, producing a list of candidate functions from the list of functions and function templates. Finally,
3. Overload resolution selects the single best choice from all the candidates.
To disable ADL, either qualify the function name
::partition(...) or parenthesize it
(partition)(...).
I guess it sees the overload resolution conflict before it even tries to parse the function generated? |
In step 2, there is an opportunity to reject function templates early, but the standard library is not taking advantage of it:
If either:
a.) template argument deduction would form an invalid type or expression in the template argument list; or
b.) template argument substitution would form an invalid type or expression in the signature of the new candidate function;
then the candidate function is discarded.
This is called
Substitution Failure is Not an Error, or SFINAE. It turns out to be a really powerful (if awkward) tool for manipulating overload resolution.
The compiler only considers the function signature. Even though a call to
std::partition wouldn't compile, it's not rejected because the candidate's signature is completely fine.
In order to exploit SFINAE here, the standard library would need to write a meta-program that provokes substitution failure when the template arguments don't meet std::partition's requirements - in this case, when the user doesn't pass a
UnaryFunction.
This is a difficult and subtle task, so C++20 is introducing a new major feature, called
concepts, to address exactly this problem:
http://www.stroustrup.com/good_concepts.pdf