我正在使用stdlib來練習一個簡單的事件系統。對繼承模板方法的模糊調用
我做了一個EventEmitter<T>
班,它提供了addListener(T)
和emitEvent(T)
。
有一個TestEmitter
類延伸EventEmitter<int>
和EventEmitter<std::string>
。 TestEmitter
類有一個emitTestEvent
方法,該方法調用emitEvent(1337)
或emitEvent(std::string("test"))
。
在main()中創建TestEmitter
的實例,併爲T = int和T = std :: string添加兩個偵聽器。
我得到了4個看起來像這樣的錯誤:reference to ‘emitEvent’ is ambiguous
。撥打電話emitEvent
兩次,撥打addListener
兩次。
下面是完整的輸出:
main.cpp: In member function ‘virtual void TestEmitter::emitTestEvent()’:
main.cpp:42:4: error: reference to ‘emitEvent’ is ambiguous
main.cpp:23:15: error: candidates are: void EventEmitter<T>::emitEvent(T) [with T = std::basic_string<char>]
main.cpp:23:15: error: void EventEmitter<T>::emitEvent(T) [with T = int]
main.cpp:45:4: error: reference to ‘emitEvent’ is ambiguous
main.cpp:23:15: error: candidates are: void EventEmitter<T>::emitEvent(T) [with T = std::basic_string<char>]
main.cpp:23:15: error: void EventEmitter<T>::emitEvent(T) [with T = int]
main.cpp: In function ‘int main(int, char**)’:
main.cpp:53:10: error: request for member ‘addListener’ is ambiguous
main.cpp:19:15: error: candidates are: void EventEmitter<T>::addListener(EventEmitter<T>::Listener) [with T = std::basic_string<char>; EventEmitter<T>::Listener = std::function<void(std::basic_string<char>)>]
main.cpp:19:15: error: void EventEmitter<T>::addListener(EventEmitter<T>::Listener) [with T = int; EventEmitter<T>::Listener = std::function<void(int)>]
main.cpp:57:10: error: request for member ‘addListener’ is ambiguous
main.cpp:19:15: error: candidates are: void EventEmitter<T>::addListener(EventEmitter<T>::Listener) [with T = std::basic_string<char>; EventEmitter<T>::Listener = std::function<void(std::basic_string<char>)>]
main.cpp:19:15: error: void EventEmitter<T>::addListener(EventEmitter<T>::Listener) [with T = int; EventEmitter<T>::Listener = std::function<void(int)>]
我以很困惑,爲什麼我收到此錯誤,編譯器(G ++)清楚地知道什麼T
是無論是通話,但它不知道哪種方法可以調用?
我能夠用EventEmitter<int>::
和EventEmitter<std::string>
前面加上他們解決在emitEvent
呼叫的錯誤,但我不知道這是否是解決這個問題的正確方法。
當編譯器知道T
的類型時,爲什麼emitEvent
和addListener
的調用不明確?我怎樣才能解決這個問題?
我希望我提供了足夠的信息,如果不讓我知道。下面的代碼:
#include <list>
#include <map>
#include <string>
#include <functional>
#include <iostream>
template<typename T>
class EventEmitter {
private:
typedef std::function<void(T)> Listener;
protected:
std::list<Listener> listeners_;
public:
EventEmitter() {};
virtual ~EventEmitter() {};
virtual void addListener(Listener listener) {
listeners_.push_back(listener);
};
virtual void emitEvent(T event) {
typename std::list<Listener>::iterator it = listeners_.begin();
for(; it != listeners_.end(); ++it) {
(*it)(event);
}
};
};
class TestEmitter : public EventEmitter<int>, public EventEmitter<std::string> {
private:
int count_;
public:
TestEmitter() {};
virtual ~TestEmitter() {};
virtual void emitTestEvent() {
count_ = (++count_) % 2;
if(count_ == 0) {
EventEmitter<int>::emitEvent(1337);
}
else {
EventEmitter<std::string>::emitEvent(std::string("test"));
}
};
};
int main(int argc, char* argv[]) {
TestEmitter emitter;
emitter.addListener([](int event) {
std::cout << "Hello: " << event << std::endl;
});
emitter.addListener([](std::string event) {
std::cout << "Bye: " << event << std::endl;
});
for(int i = 0; i < 10; i++) {
emitter.emitTestEvent();
}
return 0;
}
謝謝:)
編譯器不能找出哪些繼承的方法調用。我不知道爲什麼的確切細節,但一個解決方法是調用'emitter.EventEmitter :: addListener([](int event){/ * ... * /});''和'emitter.EventEmitter :: addListener([](std :: string event){/ * ... * /});'改爲。 –
jotik
'count_ =(++ count_)%2;'也有未定義的行爲,因爲序列點規則。取而代之的是使用'count_ =(count_ + 1)%2;' – jotik
@jotik感謝解決工作:)我會研究序列點規則,我不知道!謝謝你讓我知道。 – Bastiaanus