Template Instance Uncertainty

I play with the templated implementation FSM and see the ambiguity as follows:

/home/permal/code/FSM/Test/../FSM/dist/include/FSM.h: In instantiation of ‘void fsm::FSM<FSMBaseState>::Event(std::unique_ptr<EventType>) [with EventType = AddEvent; FSMBaseState = EventBaseState]’:
/home/permal/code/FSM/Test/test.cpp:83:44:   required from here
/home/permal/code/FSM/Test/../FSM/dist/include/FSM.h:59:4: error: request for member ‘Event’ is ambiguous
    myCurrent->Event( std::move( event ) );
    ^
In file included from /home/permal/code/FSM/Test/../FSM/dist/include/FSM.h:12:0,
                 from /home/permal/code/FSM/Test/test.cpp:8:
/home/permal/code/FSM/Test/../FSM/dist/include/EventReceiver.h:15:15: note: candidates are: void fsm::EventReceiver<EventType>::Event(std::unique_ptr<_Tp>) [with EventType = SubtractEvent]
  virtual void Event( std::unique_ptr<EventType> event ) = 0;
               ^
/home/permal/code/FSM/Test/../FSM/dist/include/EventReceiver.h:15:15: note:                 void fsm::EventReceiver<EventType>::Event(std::unique_ptr<_Tp>) [with EventType = AddEvent]
In file included from /home/permal/code/FSM/Test/test.cpp:8:0:
/home/permal/code/FSM/Test/../FSM/dist/include/FSM.h: In instantiation of ‘void fsm::FSM<FSMBaseState>::Event(std::unique_ptr<EventType>) [with EventType = SubtractEvent; FSMBaseState = EventBaseState]’:
/home/permal/code/FSM/Test/test.cpp:91:50:   required from here
/home/permal/code/FSM/Test/../FSM/dist/include/FSM.h:59:4: error: request for member ‘Event’ is ambiguous
    myCurrent->Event( std::move( event ) );

So my question is why the compiler cannot choose the right option, even if it says that there are two possible candidates, one of which is correct.

Hope the code below is enough to show the problem, the rest is available on GitHub

This is a class and method in which ambiguity arises:

template<typename FSMBaseState>
class FSM
{
public:
    ...

    template<typename EventType>
    void Event( std::unique_ptr<EventType> event )
    {
        if( HasState() )
        {
            // This way of calling causes ambiguous method lookup during template instantiation
            myCurrent->Event( std::move( event ) );

            // casting to the correct type works, but is it really needed?
            // auto* s = myCurrent.get();
            // static_cast<EventReceiver<EventType>*>( s )->Event( std::move( event ) );
        }
    }

};

The above method is called either fsm.Event( std::make_unique<AddEvent>() );orfsm.Event( std::make_unique<SubractEvent>() );

myCurrent in the above Event () - the method is an instance of the following class:

class EventBaseState
: public fsm::BaseState<EventBaseState>,
      public fsm::EventReceiver<AddEvent>,
      public fsm::EventReceiver<SubtractEvent>
{
public:
EventBaseState( const std::string& name, fsm::FSM<EventBaseState>& fsm ) :
        BaseState( name, fsm )
{}

};

where is EventReceiverdefined as follows:

template<typename EventType>
class EventReceiver
{
public:
    virtual void Event( std::unique_ptr<EventType> event ) = 0;
};

Update

, Event<T>(...), , EventBaseState .

class EventBaseState
    : public fsm::BaseState<EventBaseState>,
      public fsm::EventReceiver<AddEvent>,
      public fsm::EventReceiver<SubtractEvent>
{
public:
    EventBaseState( const std::string& name, fsm::FSM<EventBaseState>& fsm ) :
            BaseState( name, fsm )
    {}

    virtual void Event( std::unique_ptr<AddEvent> event ) override = 0;
    virtual void Event( std::unique_ptr<SubtractEvent> event ) override = 0;
};

, , Chajnik-U, .

+4
1

" " .

using EventReceiver<AddEvent>::Event;
using EventReceiver<SubtractEvent>::Event;

EventBaseState, . ( ) :

, ?

+3

Source: https://habr.com/ru/post/1656657/


All Articles