Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用enable_if解决多重继承歧义_C++_Multiple Inheritance_Name Lookup_Ambiguous Call - Fatal编程技术网

C++ 使用enable_if解决多重继承歧义

C++ 使用enable_if解决多重继承歧义,c++,multiple-inheritance,name-lookup,ambiguous-call,C++,Multiple Inheritance,Name Lookup,Ambiguous Call,我有一个事件源基类,它定义了一个用于添加侦听器的函数,我正试图使用一个模板参数来解决歧义。但这似乎不起作用-它总是使用第一个基类中的函数,然后抱怨模板参数不匹配: #include <type_traits> template<class Event> class EventSource { public: class Listener { public: virtual void handle( const Event& e ) =

我有一个事件源基类,它定义了一个用于添加侦听器的函数,我正试图使用一个模板参数来解决歧义。但这似乎不起作用-它总是使用第一个基类中的函数,然后抱怨模板参数不匹配:

#include <type_traits>

template<class Event>
class EventSource
{
public:

  class Listener
  {
  public:
      virtual void handle( const Event& e ) = 0;
  };

  template<class EventType>
  typename std::enable_if<std::is_same<Event, EventType>::value, void>::type
  addListener( Listener* ptr );
};

class Event1 {};
class Event2 {};

class MultiListener : public EventSource<Event1>::Listener, public EventSource<Event2>::Listener
{
public:
    void handle( const Event1& e );
    void handle( const Event2& e );
};

class MultiSource : public EventSource<Event1>, public EventSource<Event2>
{
public:
    void addMultiListener( MultiListener* ptr )
    {
        addListener<Event1>( ptr );
        addListener<Event2>( ptr ); // this line causes error
    }
};
#包括
模板
类事件源
{
公众:
类侦听器
{
公众:
虚拟无效句柄(常量事件&e)=0;
};
模板
typename std::enable_if::type
addListener(Listener*ptr);
};
类Event1{};
类Event2{};
类MultiListener:public EventSource::Listener,public EventSource::Listener
{
公众:
无效句柄(常数事件1&e);
无效句柄(常数事件2&e);
};
类MultiSource:public EventSource,public EventSource
{
公众:
void addMultiListener(MultiListener*ptr)
{
addListener(ptr);
addListener(ptr);//此行导致错误
}
};
为什么这不属于SFINAE


我知道我可以显式地指定基类,但是模板看起来比
EventSource::addListener(…)
好得多,因为名称查找不明确(在检查重载是否可行之前)

您可以使用

class MultiSource : public EventSource<Event1>, public EventSource<Event2>
{
    using EventSource<Event1>::addListener;
    using EventSource<Event2>::addListener;
public:
    void addMultiListener( MultiListener* ptr )
    {
        addListener<Event1>( ptr );
        addListener<Event2>( ptr );
    }
};
class MultiSource:public EventSource,public EventSource
{
使用EventSource::addListener;
使用EventSource::addListener;
公众:
void addMultiListener(MultiListener*ptr)
{
addListener(ptr);
addListener(ptr);
}
};

这两行都会导致错误,因为名称查找不明确(在检查重载是否可行之前)

您可以使用

class MultiSource : public EventSource<Event1>, public EventSource<Event2>
{
    using EventSource<Event1>::addListener;
    using EventSource<Event2>::addListener;
public:
    void addMultiListener( MultiListener* ptr )
    {
        addListener<Event1>( ptr );
        addListener<Event2>( ptr );
    }
};
class MultiSource:public EventSource,public EventSource
{
使用EventSource::addListener;
使用EventSource::addListener;
公众:
void addMultiListener(MultiListener*ptr)
{
addListener(ptr);
addListener(ptr);
}
};

您可能已经将您的案例简化为:哦,我没有意识到它即使在常规重载下也不起作用。您可能已经将您的案例简化为:哦,我没有意识到它即使在常规重载下也不起作用。因此,它会在检查该命名空间中的重载之前查找命名空间?我想我最好显式指定基类,谢谢。变量模板可能会有帮助:有趣的想法!如果我发现需要更多的多听,我会考虑,所以在检查命名空间中的重载之前,它会查找命名空间吗?我想我最好显式指定基类,谢谢。变量模板可能会有帮助:有趣的想法!如果我觉得需要更多的听众,我会考虑的。