Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Argument-dependent lookup for built in types vs user-defined types

My code:

template <typename T>
void func(T v)
{
    func2(v);
}
    
struct S {};
    
void func2(int) {}
void func2(S) {}
    
int main()
{
    func(1);  // error here
    func(S{}); // OK
}

The error:

<source>: In instantiation of 'void func(T) [with T = int]':
<source>:14:9:   required from here
   14 |     func(1);  // error here
      |     ~~~~^~~
<source>:4:10: error: 'func2' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
    4 |     func2(v);
      |     ~~~~~^~~
<source>:10:6: note: 'void func2(S)' declared here, later in the translation unit
   10 | void func2(S) {}
      | 

Why does the lookup fail for func2 with built in types but not user-defiened?

like image 250
user1166 Avatar asked Oct 20 '25 02:10

user1166


1 Answers

Fundamental types are not considered for ADL. From cppreference

Otherwise, for every argument in a function call expression its type is examined to determine the associated set of namespaces and classes that it will add to the lookup.

  1. For arguments of fundamental type, the associated set of namespaces and classes is empty.

So func2(int); has an empty set and thus the compiler error.

For the class case we have

  1. For arguments of class type (including union), the set consists of:

    a) The class itself.

    b) If the class is complete, all of its direct and indirect base classes.

    c) If the class is a member of another class, the class of which it is a member.

    d) The innermost enclosing namespaces of the classes added to the set.

and it is item d that brings in void func2(S) {} since it is in the same namespace as S.

like image 176
NathanOliver Avatar answered Oct 21 '25 21:10

NathanOliver



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!