我有一个真实的情况,可以在以下示例中进行总结:
template< typename ListenerType >
struct Notifier
{
void add_listener( ListenerType& ){}
};
struct TimeListener{ };
struct SpaceListener{ };
struct A : public Notifier< TimeListener >
, public Notifier< SpaceListener >
{
};
struct B : TimeListener{ };
int main()
{
A a;
B b;
a.add_listener( b ); // why is ambiguous?
return 0;
}
为什么对于编译器来说
B
是TimeListener
并不明显,因此唯一可能的重载解决方案是Notifier< TimeListener >::add_listener( TimeListener& )
? 最佳答案
成员名称的查找规则说您的代码不明确,因为在两个基类中找到了该名称,因此查找集无效。您无需熟悉查找集和合并的所有详细信息。重要的细节是,都检查了两个基类,并且在两个基类中都找到了名称add_listener
,这造成了歧义。
最简单的解决方法是使用using-declaration将这些基类名称添加到A
中。这意味着add_listener
的两个版本都是在A
中查找的,而不是在基类中查找的,因此没有合并歧义:
struct A : public Notifier< TimeListener >
, public Notifier< SpaceListener >
{
using Notifier<TimeListener>::add_listener;
using Notifier<SpaceListener>::add_listener;
//plus any more base classes
};