Consider the following example with several layers of inheritance:
struct A {
void operator()(double x);
};
struct B: A {
using A::operator();
template <class... T> void operator()(T... x);
};
struct C: B {
using B::operator();
void operator()() const;
void operator()(int x) const;
};
struct D: C {
using C::operator();
void operator()();
};
Will the overload resolution work exactly as if D
had been written as:
struct D {
void operator()(double x);
template <class... T> void operator()(T... x);
void operator()() const;
void operator()(int x) const;
void operator()();
};
or in the contrary, the compiler tries to find a working overload in D
, then in C
, then in B
, then in A
? In other words, does inheritance play any role in overload resolution (for functions that do not have the same signature), or not?
A general rule is that overload resolution will consider the set of declarations found by name lookup, and no others.
According to [namespace.udecl]/1:
Each using-declarator in a using-declaration introduces a set of declarations into the declarative region in which the using-declaration appears. The set of declarations introduced by the using-declarator is found by performing qualified name lookup (6.4.3, 13.2) for the name in the usingdeclarator, excluding functions that are hidden as described below.
Therefore, the name lookup of operator()
in the scope of D
, which finds D::operator()
as well as the using-declaration, must recursively look up operator()
in the scope of C
, which finds the two C::operator()
s as well as the using-declaration, and so on. So yes, in your case, overload resolution will consider the full set of operator()
s as candidates.