Home >Backend Development >C++ >Why Does Argument Dependent Lookup (ADL) Fail with Explicitly Instantiated Function Templates?
ADL and Function Template Lookup
Function templates play a significant role in C programming, enabling code reuse and generic functionality. However, a subtle limitation arises when using Argument Dependent Lookup (ADL) to locate function templates in specific namespaces.
The issue manifests itself when attempting to call a function template with explicit template arguments, as illustrated in the following code snippet:
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. }
The reason behind this failure stems from a specific clause in the C Standard. As per C Standard 03 14.8.1.6, ADL does not apply when calling function templates with explicit template arguments unless a function template with that name is visible at the point of the call.
In the example above, there is no function template named frob visible in the current scope when frob<0>(f); is called. Therefore, ADL is not triggered, and the compiler fails to find the desired function template.
To circumvent this limitation, one can explicitly specify the namespace before the function template, as shown below:
ns::frob<0>(f);
In this case, ADL is not necessary since the function template is directly invoked from the containing namespace.
The following code example further illustrates the behavior of ADL with function templates:
namespace A { struct B { }; template<int X> void f(B); } namespace C { template<class T> void f(T t); } void g(A::B b) { f<3>(b); //ill-formed: not a function call A::f<3>(b); //well-formed C::f<3>(b); //ill-formed; argument dependent lookup // applies only to unqualified names using C::f; f<3>(b); //well-formed because C::f is visible; then // A::f is found by argument dependent lookup }
In this example, the function template f is defined in both namespaces A and C. When the call f<3>(b); is made, the compiler first checks the current scope and finds no visible f template. ADL is then applied, but since f is an unqualified name, it cannot find function templates in other namespaces.
To call the template from namespace C, one must explicitly qualify the name with C::f or using directive as demonstrated in the code.
The above is the detailed content of Why Does Argument Dependent Lookup (ADL) Fail with Explicitly Instantiated Function Templates?. For more information, please follow other related articles on the PHP Chinese website!