Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't ADL find function templates?

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. } 
like image 434
Hugh Avatar asked Jun 01 '10 22:06

Hugh


People also ask

How do I instantiate a template function?

To instantiate a template function explicitly, follow the template keyword by a declaration (not definition) for the function, with the function identifier followed by the template arguments. template float twice<float>(float original); Template arguments may be omitted when the compiler can infer them.

What is function template in Object Oriented Programming?

Function Template A function template is a generic function that is defined on a generic type for which a specific type can be substituted. Compiler will generate a function for each specific type used. Because types are used in the function parameters, they are also called parameterized types.

What the function template can accept?

Explanation: As a template feature allows you to write generic programs. therefore a template function works with any type of data whereas normal function works with the specific types mentioned while writing a program. Both normal and template function accepts any number of parameters. 4.

What is the importance of function templates?

Function templates. Function templates are special functions that can operate with generic types. This allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type. In C++ this can be achieved using template parameters.


2 Answers

This part explains it:

C++ Standard 03 14.8.1.6:

[Note: For simple function names, argument dependent lookup (3.4.2) applies even when the function name is not visible within the scope of the call. This is because the call still has the syntactic form of a function call (3.4.1). But when a function template with explicit template arguments is used, the call does not have the correct syntactic form unless there is a function template with that name visible at the point of the call. If no such name is visible, the call is not syntactically well-formed and argument-dependent lookup does not apply. If some such name is visible, argument dependent lookup applies and additional function templates may be found in other namespaces.

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 } 
like image 189
Kornel Kisielewicz Avatar answered Sep 25 '22 00:09

Kornel Kisielewicz


Since c++20, adl works also fine with explicit function template. Here is the proposal: P0846R0: ADL and Function Templates that are not Visible:

Instead of requiring the user to use the template keyword, a revision to the lookup rules was proposed so that a name for which a normal lookup produces either no result or finds one or more functions and that is followed by a a "<" would treated as if a function template name had been found and would cause ADL to be performed.

Currently, only GCC 9 has implement this feature, so your example can compile.

live demo.

like image 20
Chen Li Avatar answered Sep 25 '22 00:09

Chen Li