考虑这个小例子:
#include <iostream>
struct A
{
void foo()
{
std::cout << "A::foo" << std::endl;
}
};
struct B
{
void foo()
{
std::cout << "B::foo" << std::endl;
}
};
struct C:private A
{
using A::foo;
};
struct D:private B, public C
{
};
int main()
{
D myD;
myD.foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用g ++ 4.8.1编译此示例时,我收到以下错误:
prog.cpp: In function ‘int main()’:
prog.cpp:32:9: error: request for member ‘foo’ is ambiguous
myD.foo();
^
prog.cpp:5:10: note: candidates are: void A::foo()
void foo()
^
prog.cpp:5:10: note: void A::foo()
prog.cpp:13:10: note: void B::foo()
void foo()
Run Code Online (Sandbox Code Playgroud)
我原以为D :: foo()的查找会忽略B :: foo(),因为B是私有地继承自D而且D中没有using声明.我会认为唯一可见的foo()会是A :: foo的().
但显然我认为错了,我误解了using宣言的一个方面.
谁能解释一下:
为什么B :: foo()在这里可见
如何使编译器只看到A :: foo()而不改变A,B或C的公共接口?
1)在名称查找期间忽略可访问性:成员是公共的,私有的还是受保护的并不重要:所有都被同等考虑,这就是为什么A::foo并且B::foo内部含糊不清D.
C++标准第3.4节[basic.lookup]:
访问规则(第11条)仅在名称查找和功能重载解析(如果适用)成功后才被考虑
2)简单地将其纳入以下范围D:
struct D: private B, public C
{
using C::foo;
};
Run Code Online (Sandbox Code Playgroud)