When is there an UB because the best overload match was not found by ADL at the point of instantiation?

Viewed 151

When a function body is instantiated, dependent function call overload resolution should find the best match in associated namespace through ADL, otherwise the behavior is undefined, [temp.dep.candidate]§1

If the call would be ill-formed or would find a better match had the lookup within the associated namespaces considered all the function declarations with external linkage introduced in those namespaces in all translation units, not just considering those declarations found in the template definition and template instantiation contexts, then the program has undefined behavior.

For exemple:

struct A {
    friend void f(A a){};
};

struct B : A {};

template <class T> 
void g (T a) {
    f(a);
}

void h(B b){
    g(b);//undefined behavior (UB)
}
 //TU2.cpp
 //...
void f(B){}

I have 2 doubts about which functions could be one of all the function declarations with external linkage introduced in those namespaces

Question 1

Does inline friend function considered to be introduced in the enclosing namespace?

Exemple:

struct A {
    friend void f(A a){};
};

struct B : A {};

template <class T> 
void g (T a) {
    f(a);
}

void h(B b){
    g(b);//undefined behavior ??
}
//TU2.cpp
//....
struct C {
   operator B();
   friend void f(B){}
   };

Question 2

Could function template specialization also trigger this undefined behavior? (Potentialy instantiated or instantiated function template specialization)

Exemple:

struct A {
    friend void f(A a){};
};

struct B : A {};

template <class T> 
void g (T a) {
    f(a);
}

void h(B b){
    g(b);//undefined behavior ??
}
//TU2.cpp
//...
template <class T> void f(T){}

// optionaly also with:
// template void f(B);
0 Answers
Related