What part of the C++ specification restricts argument dependent lookup from finding function templates in the set of associated namespaces? In other words, why does the last call in main
below fail to compile?
namespace ns {
struct foo {};
template<int i> void frob(foo const&) {}
void non_template(foo const&) {}
}
int main() {
ns::foo f;
non_template(f); // This is fine.
frob<0>(f); // This is not.
}
Edit: No, this is not right. See @Kornel's answer.
I'm not entirely sure but having consulted Stroustrup's "The C++ programming language" I think that Appendix C section 13.8.4 might be the cause.
Since
frob
is a template one could conceivably specialise it fori=0
at a point after you call it. This means that the implementation would be left with two possible ways of choosing whichfrob
to call as it appears it can choose it at the point of instantiation or at the end of processing the translation unit.So, I think the problem is you could do
Since c++20, adl works also fine with explicit function template. Here is the proposal: P0846R0: ADL and Function Templates that are not Visible:
Currently, only GCC 9 has implement this feature, so your example can compile.
live demo
.This part explains it:
C++ Standard 03 14.8.1.6:
I would like to refine slightly accepted answer. It is not clear in the OP question, but the important part from the standard (cited by Kornel) is this (emphasis mine):
so what is prohibited is relying on ADL and using explicit template arguments. Unfortunately using non-type template arguments requires using explicit arguments (unless they have default values).
Below is sample code showing this.:
[live]