请考虑以下几个继承层的示例:
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()();
};
重载决策是否会像D
写成:
struct D {
void operator()(double x);
template <class... T> void operator()(T... x);
void operator()() const;
void operator()(int x) const;
void operator()();
};
或者相反,编译器试图在D
中查找工作重载,然后在C
中找到,然后在B
中,然后在A
中?换句话说,继承是否在重载解析(对于没有相同签名的函数)中起任何作用?
一般规则是重载解析将考虑通过名称查找找到的声明集,而不考虑其他声明。
根据[namespace.udecl] / 1:
using声明中的每个using-declarator都会在声明区域中引入一组声明,其中出现using声明。 using-declarator引入的声明集是通过对usingdeclarator中的名称执行限定名称查找(6.4.3,13.2)找到的,不包括如下所述隐藏的函数。
因此,在operator()
范围内找到D
的D::operator()
的名称查找以及使用声明,必须在operator()
的范围内递归查找C
,它找到两个C::operator()
s以及using声明,等等上。所以是的,在你的情况下,重载决议会将全套operator()
s视为候选者。
D::operator()
隐藏了父母的超载。
你必须使用C::operator()
(和其他基础相同)。
然后所有重载都可见。