here is code, c++11:
#include <string>
#include <boost/signals2/signal.hpp>
namespace messages {
struct Event1 final {};
struct Event2 final {};
template <typename T, typename Tag>
class EventHandler {
protected:
bool cache_valid_ = false;
T cache_val_;
boost::signals2::signal<void (const T&)> signal_;
using slot_type = typename decltype(signal_)::slot_type;
using connection = boost::signals2::connection;
public:
EventHandler() {}
void emit(Tag, const T& val) {
if (val != cache_val_) {
cache_valid_ = true;
cache_val_ = val;
signal_(val);
}
}
connection subscribe(Tag, slot_type slot) {
if (cache_valid_)
slot(cache_val_);
return signal_.connect(slot);
}
};
}
struct MessageBus : public messages::EventHandler<int, messages::Event1>,
public messages::EventHandler<std::string, messages::Event2> {
};
int main()
{
MessageBus bus;
bus.subscribe(messages::Event1(), [](const int& val) {});
}
recent versions of gcc and clang can not compile this code with -std=c++11
, they can not decide what overload to choose here: bus.subscribe(messages::Event1(), [](const int& val) {});
.
1) Why, they can not choose appropriate method? There is only one MessageBus::subscribe
, which accept Event1
type as first argument
2)How fix this issue, without MessageBus
modifications?
I can fix this issue by this code:
struct MessageBus : public messages::EventHandler<int, messages::Event1>,
public messages::EventHandler<std::string, messages::Event2> {
using messages::EventHandler<int, messages::Event1>::subscribe;
using messages::EventHandler<std::string, messages::Event2>::subscribe;
};
but the whole idea behind messages::EventHandler
to reduce efforts for introduction of new message, so it would be good to fix this problem by modification messages::EventHandler
in some way.