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.
D::operator()
hides overloads of parent.
You have to write using C::operator()
(and same for other bases).
Then all overloads are visible.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.