我玩弄的FSM的templated implementation和如下我遇到的歧義:模板實例歧義
/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));
所以我的問題是爲什麼編譯器不能選擇正確的選項,即使它闡明瞭這有兩個可能的候選人,其中一個是正確的。
我希望下面的代碼,就足以說明問題,剩下的就是可在GitHub
這是歧義發生的類和方法:
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));
}
}
};
上述方法要麼叫作爲fsm.Event(std::make_unique<AddEvent>());
或fsm.Event(std::make_unique<SubractEvent>());
在上述事件myCurrent
() - 方法是下面的類的一個實例:
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)
{}
};
其中EventReceiver
定義如下:
template<typename EventType>
class EventReceiver
{
public:
virtual void Event(std::unique_ptr<EventType> event) = 0;
};
更新
從一個新的角度事情來看,我結束了一個純虛函數的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提供的解決方案也適用。
'myCurrent->事件(標準::移動(事件));'這是重要的線。什麼是'myCurrent'和'event'的類型?在調用'myCurrent-> Event(std :: move(event))的函數中究竟是如何確切定義了這兩個變量的?' –
@AaronMcDaid問題在於:'myCurrent'是'EventBaseState','event'是'std :: unique_ptr'或'std :: unique_ptr '。 –
Rakete1111