I need a way to store a list of method pointers, but I don't care about what class they belong to. I had this in mind:
struct MethodPointer
{
void *object;
void (*method)(void);
};
Then I could have have a function which takes an arbitrary method:
template <typename T>
void register_method(void(T::*method)(void), T* obj) {
MethodPointer pointer = {obj, method);
}
void use_method_pointer() {
...
MethodPointer mp = ...
// call the method
(mp.object->*method)();
...
}
This obviously doesn't compile because I can't convert the method pointer into a function pointer in register_method().
The reason I need this is because I have a class which can emit events - and I want arbitrary instances to subscribe to these events as method calls. Is this possible to do?
PS. Conditions apply:
1. I don't want to use Boost
2. I don't want to use a 'Listener' interface, where a subscriber have to subclass an abstract interface class.
Thank you for your time.
I believe you are just looking for std::function:
using NullaryFunc = std::function<void()>;
Registration:
template <typename T>
void register_method(void(T::*method)(void), T* obj) {
NullaryFunc nf = std::bind(method, obj);
// store nf somewhere
}
Usage:
void use_method() {
...
NullaryFunc nf = ...;
// call the function
nf();
...
}
Related
Is there a way in C++11, to create a container with map of interfaces as key and implementation classes as value of that key. What I want to do, is to be able to bind interfaces with certain implementations, then instantiate quickly class assigned to that interface. I'll explain using code:
Locator locator;
// binding ILogisticsCarrierPairingModel with DummyModel:
locator.bind<ILogisticsCarrierPairingModel, DummyModel>();
// instantiating DummyModel, by calling function with interface name:
ILogisticsCarrierPairingModel* model2 = locator.get<ILogisticsCarrierPairingModel>();
// binding ILogisticsCarrierPairingModel with LogisticsCarrierPairingModel:
locator.bind<ILogisticsCarrierPairingModel, LogisticsCarrierPairingModel>();
// now instantiating LogisticsCarrierPairingModel, by calling function with interface name:
model2 = locator.get<ILogisticsCarrierPairingModel>();
Thanks in advance.
This is an alternative technique that doesn't do a runtime map. It requries that your Locator be a singleton.
struct Locator {
// default constructor:
template<class I, class T>
void bind() {
factory<I>() = []{ return std::make_unique<T>(); }
}
// with custom factory object:
template<class I, class F>
void bind(F f) {
factory<I>() = std::forward<F>(f);
}
template<class I>
std::unique_ptr<I> get() {
auto&& f = factory<I>();
if (!f) return nullptr;
return f();
}
private:
template<class I>
static std::function<std::unique_ptr<I>()>& factory() {
static std::function<std::unique_ptr<I>()> f;
return f;
}
};
I took the liberty of adding unique ptr based memory management.
The trick here is that factory<I>() creates storage at compile time for a factory object (a std::function) for each interface. It gets populated by a call to bind<I,T>(), and used by a call to get<I>().
The storage is created at compile time, because the compiler knows every I passed to either bind or get. The storage for the factory is only populated after you call bind.
This lets you dynamically pick what implementation class (or factory for said class) you use at runtime, or even change them. But the entire program has to agree on the same one.
You cannot use this technique easily if you want to have an arbitrary number of Locators; I mean, you can, if you give each a unique id, and store a map from that id to the function instead of a single function in factory.
But, when there is one mapping, and one type, you can avoid any kind of dynamic lookup with this trick.
As #HolyBlackCat suggested you can use the runtime type id as a map key.
std::map<std::type_id, ValueType> bindings;
Since you want to lazily instantiate the implementation, you probably need to store a pointer to a function that does so:
class BindingBase {
virtual ~BindingBase() = default;
};
template <class Interface>
class Binding : public BindingBase {
public:
template <class Implementation>
Binding(std::in_place_type_t<Implementation>) : instantiator([]() { return std::make_unique<Implementation>(); }) {
static_cast(std::is_base_of<Interface, Implementaiton>::value);
}
Interface &get() {
if (!implementation)
implementation = instantiator();
return *implementation;
}
private:
using ConstructFn = std::unique_ptr<Interface> (*)();
ConstructFn instantiator;
std::unique_ptr<Implementation> implementation;
};
std::map<std::type_id, std::unique_ptr<BindingBase>> bindings;
// bind<Interface, Implementation>
bindings[typeid(Interface)] = std::make_unique<Binding<Interface>>(std::in_place_type<Implementation>);
// get<Interface>
Interface *result = std::dynamic_cast<Binding<Interface>>(bindings.at(typeid(Interface))).get();
I am trying to generalize a callback mechanism.
I need two things for that:
Calling it in a general matter: void call() - that I was able to manage
I mean that everyone can get a void call() function, and I can even (easily) store them in an array. They are all of the same type.
class Function{
public:
virtual void call()=0;
};
template<typename T>
class TemplatedFunction : public Function{
public:
int (T::*m_fkt)();
T* m_obj;
TemplatedFunction(T* obj, int (T::*fkt)()):m_fkt(fkt),m_obj(obj){}
// Can also set here a [&](){ f(Args...args) } that will capture the callback arguments, and call it via call(). f being the std::function created for the callback.
void call(){
(m_obj->*m_fkt)();
}
};
Set (register callback) in a general matter: here I got lost...
My callbacks are statically allocated.
I saw this great option, but my only option is using a capturing lambda.
( no bind, or tuple.. )
This option is great as I can store an array of EventHandler that basically will differ by the ID of a message I will get. Unfortunately I can't use new. (I use an in place static allocation for lambda)
class EventHandler{
public:
Function* m_func=nullptr;
template<class T>
void SetCallbackFunction(T* obj, void (T::*mem_fkt)()){
if(m_func != nullptr)
delete m_func;
m_func = new TemplatedFunction<T>(obj,mem_fkt); // can't use it.
}
void TestCallback(){
if(m_func != nullptr)
m_func->call();
}
~EventHandler(){
if(m_func != nullptr)
delete m_func;
}
};
As of my callbacks are statically allocated in advanced, containing the option to call, but not to set.
I know that there are many designs available, but I am limited to using a capturing lambda only with an std::function replacement to store it.
My goal is to pass a single type EventHandler to all my messages, without the need to template the messages, so I will be able to store them in a std::array<Msg_t>
here how I want it to look in the end:
// Statically allocated callbacks that have general `void call()`
//Function* m_func_to_run_callback1 = TemplatedFunction<> Callback1();
// Function* m_func_to_run_callback2 = TemplatedFunction<> Callback2();
int main()
{
EventHandler eh, eh1;
Foo foo; // some class
Foo2 foo2; // some other class
eh.SetCallbackFunction(&foo, &Foo::bar, m_func_to_run_callback1 ) ;
eh1.SetCallbackFunction(&foo2, &Foo2::bar2, m_func_to_run_callback1) ;
return 0;
}
I think that what I am missing is :
class Function{
public:
virtual void call()=0;
virtual void set(void*) = 0; // void* being the callback function
};
How do I do to call a specific method present on all classes from an other (TranslationManager) class ?
I simplified a lot the code. I just want to call the setTranslationText of any class from TranslationManager.
These are to take in consideration:
All classes have a setTranslationText method
We should call setTranslationText of any class from TranslationManager by using the pointer to the class
class Interface
{
...
public:
void setTranslationText(QString translatedString);
}
class AnyOtherInterface
{
...
public:
void setTranslationText(QString translatedString);
}
...
…
Translationmanager::Translationmanager(){
AnyClass = Interface; // Pointer to Interface Class
AnyClass->setTranslatioNText("Text");
AnyClass = AnyOtherInterface; // Pointer to AnyOtherInterface Class
AnyClass->setTranslatioNText("AnotherText");
}
…
You could use a template
template <typename T>
void setTranslationText(T* t, const QString &translatedString)
{
t->setTranslationText(translatedString);
}
That way you wouldn't need an interface class just to inherit for this one (or however many) methods. Then the template would only compile if for a given class instantiation they had a setTranslationText method defined. The way you'd use it is
Translationmanager::Translationmanager()
{
setTranslationText(Interface, "Text"); // Pointer to Interface Class
setTranslationText(AnyOtherInterface, "AnotherText"); // Pointer to AnyOtherInterface Class
}
Adding to Cory's answer: If you're using C strings to initialize QString, you shouldn't depend on the implicit conversion - instead, make your use case explicit:
template <typename T>
void setTranslationText(T* t, const char *translatedString) {
t->setTranslationText(QString::fromUtf8(translatedString));
}
I wasn't precise about what I wanted. I finally found the best solution to my problem: callback.
Solution found on: C++ class member callback simple examples
std::vector<std::function<void(std::string,std::string)>> callbacks;
template<class T> void addTranslationText(T* const object, void(T::* const mf)(std::string,std::string)){
using namespace std::placeholders;
callbacks.emplace_back(std::bind(mf, object, _1, _2));
}
...
// Call callback
callbacks.at(0)(std::string("arg1"), std::string("arg2"));
I have a class called "Tasks" that needs to store methods from other classes, and be able to execute them. I'd like it to work like this:
Window *window = new Window();
Tasks* tasks = new Tasks();
tasks.m_tasks.Add(window.Create("My Window"));
Then I could call that window creation from my tasks class, by iterating over the stored tasks and executing each one:
tasks.ExecuteTasks();
What would be the datastructure of "m_tasks" that stores the functions, and how could I call them?
I would use a std::list<std::function<void()> >, or boost::function if std::function is not available.
And you'll need to change the syntax of that Add call to avoid executing the Create method right away.
C++11:
class Tasks {
public:
void Add(const std::function<void()>& f)
{ callbacks_.push_back( f ); }
void Add(std::function<void()>&& f)
{ callbacks_.emplace_back( std::move( f ) ); }
// ...
private:
std::list<std::function<void()> > callbacks_;
};
int main() {
Window window;
// ...
tasks.Add( [&]() { window.Create("My Window"); } );
// ...
}
C++03:
class Tasks {
public:
void Add(const boost::function<void()>& f)
{ callbacks_.push_back( f ); }
private:
std::list<boost::function<void()> > callbacks_;
};
int main() {
// ...
tasks.Add( boost::bind( &Window::Create, boost::ref(window), "My Window" ) );
// ...
}
You could use a list of tr1 or boost ::functions as #aschepler says, but this scenario is perfect for boost::signals.
class Tasks {
boost::signal<void ()> m_tasks;
};
// ...
tasks.m_tasks.connect(&someFunction);
// ExecuteTasks:
tasks.m_tasks();
This allows for a lot of extra functionality, like handling arguments, returns, and letting clients disconnect their tasks if they want to.
You'll need slightly complicated structure for this:
class Task
{
public:
virtual void Execute()=0;
};
template<class T, class R, class P1>
class Function1 : public Task
{
public:
Function1(T *ptr, R (T::*fptr)(P1), P1 p1) : ptr(ptr), fptr(fptr),p1(p1) { }
void Execute() { (ptr->*fptr)(p1); }
private:
T *ptr;
R (T::*fptr)(P1);
P1 p1;
};
std::vector<Task*> vec;
This is relatively straightforward if you know what the arguments will be. You could use a function pointer, with some extras to make it a 'method' pointer. See:
http://mdzahidh.wordpress.com/2008/07/16/pointer-to-c-class-methods-or-should-you-call-em-method-pointers/
However, this would not allow you to pass arbitrary arguments. You might be able to do it with C++ templates, but it would be nasty hackery. I would strongly advise avoiding this and going with traditional function/method pointers if at all possible.
m_tasks is going to be a collection of some sort, I'd probably use a list unless you need to be able to add/remove in the middle. The thing you will be storing in the list is a function pointer. That is, a pointer to a function. With the straightforward version of the code I have below, you cannot have generic function pointers, you must be specific about the parameter types and the return value type. It might be possible to use templates to break this restriction. I don't know off the top of my head.
// define FunctionPtr as a pointer to a function that takes a single char* param and returns void
typedef void(*FunctionPtr)(char*);
// define an stl:list of FunctionPtr items
std:list<FunctionPtr> m_tasks;
I am working on an event daemon in C++ that I would like to use member function callbacks. Basically an event queue would collect events which the daemon continuously services. There is a base class Event struct with an ID and all events would derive from it. I would like the methods registered for each event to use the derived event type in their signature.
struct Event
{
unsigned int eventId;
};
struct EventA : public Event
{
unsigned int x;
unsigned int y;
};
// and struct EventB, EventC (use your imagination...)
const unsigned int EVENT_A = 1;
const unsigned int EVENT_B = 2;
const unsigned int EVENT_C = 3;
class Foo
{
public:
void handlerMethod_A(const EventA& e);
void handlerMethod_B(const EventB& e);
};
class Bar
{
public:
void handlerMethod_C(const EventC& e);
};
Then the Daemon would allow these classes to subscribe their member functions using their 'this' pointer.
class EventDaemon
{
public:
void serviceEvents();
template <class CallbackClass, class EventType>
void subscribe(
const unsigned int eventId,
CallbackClass* classInstancePtr,
void (CallbackClass::*funcPtr)(EventType));
private:
Queue<Event*> eventQueue_;
};
So outside this class you could do something like:
EventDaemon* ed = new EventDaemon();
Foo* foo = new Foo();
Bar* bar = new Bar();
ed->subscribe(EVENT_A, foo, Foo::handlerMethod_A);
ed->subscribe(EVENT_B, foo, Foo::handlerMethod_B);
ed->subscribe(EVENT_C, bar, Bar::handlerMethod_C);
And the EventDaemon loop would be along the lines of
void EventDaemon::serviceEvents()
{
while (true)
{
if (eventQueue_.empty())
{
// yield to other threads
}
else
{
// pop an event out of the FIFO queue
Event e* = eventQueue_.pop();
// somehow look up the callback info and use it
classInstancePtr->*funcPtr(reinterpret_cast<?*>(e));
}
}
}
So my question is how I can store the 'this' pointers and member function pointers in some sort of array by event ID. That way I could look up the 'classInstancePtr' and 'funcPtr' by using e->eventId and the event type as well for the reinterpret cast.
You are working too hard. Use boost functions:
http://www.boost.org/doc/libs/1_47_0/doc/html/function.html
These work whether you have a object or not. They will increase your compile time.
Note, whenever you come across these types of questions where you know many people must have had the same problem, there is probably a simple option and, if it is not in the standard library, it is probably in boost.
In response to Nick, I'm constantly throwing boost function objects into vectors and whatnot.
I've found that, while boost function objects can hold object references, having them do so can lead to bugs with object lifetimes and it is better to have them hold copies of the class objects (you run into the same bugs however you try to hold a reference to a object instance that you don't necessarily control the lifetime of). The pattern:
class Foo
{
struct Member
{
// member variable definitions
};
shared_ptr<Member> m_; // the only real member variable
public:
// etc. including the all-important copy
// constructor and assignment operator and
// don't forget the member function that gets stuck into
// the boost function as a callback!
};
where all the member variables get held in a shared_ptr allows for good performance and you don't have to worry about lifetimes of objects held by function objects because you can copy them by value. Threaded code (what I always seem to be writing nowadays) needs additional things like at least one boost mutex element in Member or some other way to assure values don't get stomped on.
boost::function [or, if your system supports it, std::function] will take care of holding the this pointer quite well, with the added benefit of not requiring an actual object if it isn't necessary. So instead of void (SomeType::*)(EventA) you have std::function<void(EventA)>, and you call std::bind as appropriate.
subscribe(EVENT_A, std::bind(&foo::handleEventA, &foo, std::placeholders::_1));
A trivial wrapper function can be used to provide the same signature as you originally proposed and hide the nasty placeholders.
You do, of course, still have the issue of each event type having its own signature, and the need to ensure you use the correct Event ID code. In both cases, your base Event type can help out. Your callback need not accept an EventA&; it can accept an Event&, and dynamic_cast it to an EventA at runtime. For the ID, query the type directly.
struct Event {
virtual void ~Event() { }
virtual int ID() =0;
};
template<typename E>
struct EventHelper : Event {
virtual int ID() { return E::EventID; }
};
struct EventA : EventHelper<EventA> {
static const int EventID = 89;
};
Now, if you have an Event* object [when you go to dispatch your events], you can do p->ID() to get the appropriate ID, and if you have a EventA type [when you register your callbacks] you can do EventA::EventID.
So now, all you have to store is a std::function<void(const Event&)> and an associated int value for each of your callbacks, no matter what the actual type of event you have.
void subscribe(int id, std::function<void(const Event&)> f) {
callbacks.insert(std::make_pair(id, f));
}
template<typename E>
void subscribe(std::function<void(const Event&)> f) {
subscribe(E::EventID, f);
}
template<typename O, typename E>
void subscribe(O* p, void (O::*f)(const Event&)) {
subscribe<E>(std::bind(f, p, std::placeholders::_1));
}
You still have the issue that user error when subscribing can result in a function being called incorrectly. If you've used dynamic_cast correctly within the callback, this will get caught at runtime, but a compile time check would be nice. So what if we automate that dynamic_cast? For this step, I'm going to use c++11 lambdas, but it can be implemented in C++03 as well using a variety of methods.
template <class CallbackClass, class EventType>
void subscribe(CallbackClass* classInstancePtr, void (CallbackClass::*funcPtr)(EventType)) {
subscribe<EventType::EventID>([&](const Event& e) {
(classInstancePtr->*funcPtr)(dynamic_cast<const EventType&>(e));
});
}
So now we've gone full circle back to your original interface where your callbacks accept the actual type they are going to be working on, but internally you've squeezed them all into a common signature.
Okay, so I finished an implementation of my original desired interface. I was looking through Dennis' answer but eventually got lead to functors and I realized what I was looking for was a simple polymorphic solution. I failed to grasp before that I could create a non-templated base class with which to use for storing templated classes in vectors/arrays. I think this is what mheyman was trying to tell me... so I apologize I didn't get it right away. Just to clarify though I was really looking for the implementation solution for my own benefit and knowledge, not just a 3rd party library to get the job done. So I guess I would be looking for how Boost functions work, not just that they exist and are awesome.
If anyone is still interested here are the important parts of what I ended up with (minus some extraneous stuff and error checking):
EventFunctor is basically a pointer to member function template class
EventFunctorBase is the non-templated base class used to store them in a vector
The Event is dynamic cast using the templated type before being used to invoke the callback
class EventDaemon
{
public:
template <class CallbackClass, class EventType>
void subscribe(
const EventId eventId,
CallbackClass* callbackClassInstancePtr,
void (CallbackClass::*funcPtr)(const EventType&));
private:
EventFunctorBase* callbacks_[MAX_NUM_EVENTS];
};
template <class CallbackClass, class EventType>
void EventDaemon::subscribe(
const EventId eventId,
CallbackClass* callbackClassInstancePtr,
void (CallbackClass::*funcPtr)(const EventType&))
{
callbacks_[eventId] = new EventFunctor<CallbackClass,EventType>(callbackClassInstancePtr,funcPtr);
}
class EventFunctorBase
{
public:
EventFunctorBase();
virtual ~EventFunctorBase();
virtual void operator()(const Event& e)=0;
};
template <class CallbackClass, class EventType>
class EventFunctor : public EventFunctorBase
{
public:
EventFunctor(
CallbackClass* callbackClassInstancePtr,
void (CallbackClass::*funcPtr)(const EventType&));
virtual void operator()(const Event& e);
private:
CallbackClass* callbackClassInstancePtr_;
void (CallbackClass::*funcPtr_)(const EventType&);
};
template <class CallbackClass, class EventType>
EventFunctor<CallbackClass,EventType>::EventFunctor(
CallbackClass* callbackClassInstancePtr,
void (CallbackClass::*funcPtr)(const EventType&))
:
callbackClassInstancePtr_(callbackClassInstancePtr),
funcPtr_(funcPtr)
{
}
template <class CallbackClass, class EventType>
/*virtual*/ void EventFunctor<CallbackClass,EventType>::operator()(const Event& e)
{
(callbackClassInstancePtr_->*funcPtr_)(dynamic_cast<const EventType&>(e));
}
EventDaemon loop
while (true_)
{
if (eventQueue_->empty())
{
// yield to other threads
}
else
{
Event* e = eventQueue_.pop();
(*(callbacks_[e->ID]))(*e);
}
}
My final steps here will be to try and remove the need to have the developer define an ID for each event... of course this might end up a new post later this week.