C++ multiple callback member functions from different classes without std and boost - c++

I'm new to C++ and I don't want to use any libraries because I want to really understand whats going on internally.
Additionally I try to keep my library-use as low as possible (to improve performance and) to make it as platform-independent as possible (without exporting the library).
So all in all I'd like to not use std or boost to solve this problem.
My question:
I have an EventHandler which has a function:
template<class T> void EventHandler::SetCallbackFunction(T* obj, void (T::*mem_fkt)(void));
I have to save the object and the function to call it later.
There are 2 possibilities:
EventHandler as template class (and typedef)
void* -> but to call the function I need to cast it back and for that I need the classname :/
Why these dont work:
- The EventHandler can't be a template class because it needs to handle multiple classes..
- void* -> I don't know how to save the classname to cast it later on
How can I do that?
(Or is there another way? Maybe a way to save the classname to cast it later on?)
EDIT:
Furthermore I may need to register multiple callback functions per class so an Interface is not really an option.
class A {
public:
void CallbackFktForEventHandler();
void CallbackFktForAnimationHandler();
etc...
};
And I know that you could solve it based on something like this:
class A{
public:
void Callback();
static void CallbackStatic(void* self){
static_cast<A*>->CallBack();
};
};
But this restricts me too much for my taste.

You could try this:
Create a (pure virtual) base-class that only has one function call():
class Function{
virtual void call()=0;
}
Create a templated class which stores a function-pointer and an object and make it inherit from Function
template<typename T>
class TemplatedFunction{
void (T::*m_fkt)(void);
T* m_obj;
TemplatedFunction(T* obj, void (T::*fkt)(void)):m_fkt(fkt),m_obj(obj){}
void call{
(m_obj->*m_fkt)();
}
}
And then store pointers to Function in your Event-Handler and just use Function->call()
Try it online: http://ideone.com/3Hu5pw
But you will make your life a lot easier if you use at least the standard library. Basically i would use std::bind to bind your object and your member-function together to a function void()(void) and then store these objects inside a std::vector.
Edit: Oktalist was faster ;)

You can use type erasure. You effective save the type of obj by instantiating a class template which implements a non-template virtual interface. This is essentially how std::function is implemented, so you're just writing your own basic version of std::function.
struct ICallback
{
virtual void call() = 0;
};
template <class T>
struct Callback : public ICallback
{
virtual void call() override { (m_obj->*m_func)(); }
Callback(T *obj, void (T::*func)()) : m_obj(obj), m_func(func) {}
T *m_obj;
void (T::*m_func)();
};
template <class T>
std::unique_ptr<ICallback> wrap(T *obj, void (T::*func)())
{
return std::make_unique<Callback<T>>(obj, func);
}
If you don't want to use std::unique_ptr you can roll your own or use an evil raw owning pointer.

Related

Overhead of std::function vs virtual function call for type erasure

Say I have a templated class that wraps its template argument to provide some extra functionality, like the ability to persist the object's state to disk:
template<typename T>
class Persistent {
std::unique_ptr<T> wrapped_obj;
public:
Persistent(std::unique_ptr<T> obj_to_wrap);
void take_snapshot(int version);
void save(int to_version);
void load(int to_version);
}
I want to have another class, let's call it PersistentManager, store a list of these templated Persistent objects and call their member methods without knowing their template parameters. There are two ways I can see to do that: use std::function to erase the template type from each method, or use an abstract base class and virtual function calls.
Using std::function, each Persistent object would be capable of returning a bundle of std::functions bound to its members:
struct PersistentAPI {
std::function<void(int)> take_snapshot;
std::function<void(int)> save;
std::function<void(int)> load;
}
template<typename T>
PersistentAPI Persistent<T>::make_api() {
using namespace std::placeholders;
return {std::bind(&Persistent<T>::take_snapshot, this, _1),
std::bind(&Persistent<T>::save, this, _1),
std::bind(&Persistent<T>::load, this, _1)}
}
Then the PersistentManager can store a list of PersistentAPIs, and have a method like this:
void PersistentManager::save_all(int version) {
for(PersistentAPI& bundle : persistents) {
bundle.save(version);
}
}
Using inheritance, I would create an abstract class with no template parameters that defines each of Persistent's methods as virtual, and make Persistent inherit from it. Then the PersistentManager can store pointers to this base class, and call the Persistent methods through virtual function calls:
class AbstractPersistent {
public:
virtual void take_snapshot(int version) = 0;
virtual void save(int to_version) = 0;
virtual void load(int to_version) = 0;
}
template<typename T>
class Persistent : public AbstractPersistent {
...
}
void PersistentManager::save_all(int version) {
for(AbstractPersistent* obj : persistents) {
obj->save(version);
}
}
Both of these approaches add some overhead to the function call from PersistentManager: rather than dispatching the function call directly to a Persistent instance, they require going through an intermediary layer, either the std::function object or the virtual function table in AbstractPersistent.
My question is, which approach adds less overhead? Since these are both fairly opaque parts of the standard library, I don't have a good sense of how "expensive" a std::function call is compared to a virtual function call through a base class pointer.
(I've found a few other questions on this site asking about the overhead of std::function, but they all lack a specific alternative to compare against.)
I was hesitating a bit to answer this question, since it could easily boil down to opinions. I have been using std::function in a project, so I might just as well share my two cents (and you can decide what to do with the input).
Firstly, I would like to iterate what's already been said in the comments. If you actually want to see the performance, you have to do some benchmarking. Only after benchmarking, you can derive your conclusions.
Luckily, you can use quick-bench for quick benchmarking(!). I fed the benchmark with your two versions, adding a state that is increased for each call, and a getter for the variable:
// Type erasure:
struct PersistentAPI {
std::function<void(int)> take_snapshot;
std::function<void(int)> save;
std::function<void(int)> load;
std::function<int()> get;
};
// Virtual base class
class AbstractPersistent {
public:
virtual void take_snapshot(int version) = 0;
virtual void save(int to_version) = 0;
virtual void load(int to_version) = 0;
virtual int get() = 0;
};
Each function simply increases an integer in the corresponding class, and returns it with get() (hoping that the compiler does not remove all unnecessary code).
The result is in favor of virtual functions, and for both Clang and GCC, we have around 1.7 speed difference (https://quick-bench.com/q/wUbPp8OdtzLZv8H1VylyuDnd2pU, you can change compiler and recheck).
Now to the analysis: why is the abstract class seemingly quicker? Well, there are more indirections with std::function, but also there's another indirection in the wrapping before, when we call std::bind(!). Listening to Scott Meyers, lambdas are to prefer over std::bind, not only for their ease of syntax for people (std::placeholders is no beauty), but their of syntax for the compiler! A lambda call is easier to inline.
Inlining is very important for performance. If a explicit call can be avoided by added the code where we call, we can save some cycles!
Changing std::bind to lambdas, and performing again, we have very similar performance between std::function and inheritance (for both Clang and GCC): https://quick-bench.com/q/HypCbzz5UMo1aHtRpRbrc9B8v44.
So, why are they similar? For Clang and GCC, std::function is internally using inheritance. Type erasure, as it is implemented here, is simply hiding the polymorphism.
(Note that this benchmark might be misleading, since the call for both cases could be completely inlined, thus no indirection is used at all. The test case might have to be a bit more tricky to trick the compiler.)
So let's say you have either Clang and GCC as compilers, which method should you use?
The PersistentAPI is more flexible, since actually take_snapshot, save and load are basically function pointers, and do not need to be assigned to a single class! With
struct PersistentAPI {
std::function<void(int)> take_snapshot;
std::function<void(int)> save;
std::function<void(int)> load;
};
, it is fully reasonable as a developer to believe that PersistentAPI is meant to dispatch to multiple objects, and not just a * single one*. take_snapshot could for example dispatch to a free function, whereas save and load to two different classes. Is this the flexibility you want? Then that's what you should use. Generally, I would use std::function through the API to let the user register a callback to any callable of choice.
If you want to use type erasure, but want to hide the inheritance for some reason, you could build your own version. std::function accepts all types having operator(), we can build one that accepts all classes having the interface "take_snapshot, save and load". It's good to practice!
// probably there is a better name for this class
class PersistentTypeErased {
public:
template<typename T>
PersistentTypeErased(T t) : t_(std::make_unique<Model<T>>(t)) {}
void take_snapshot(int version) { t_->take_snapshot(version); }
void save(int to_version) { t_->save(to_version); }
void load(int to_version) { t_->load(to_version); }
private:
struct Concept
{
virtual void take_snapshot(int version) = 0;
virtual void save(int to_version) = 0;
virtual void load(int to_version) = 0;
};
template<typename T>
struct Model : Concept
{
Model(T t) : t_(t) {}
void take_snapshot(int version) { t_.take_snapshot(version); }
void save(int to_version) { t_.save(to_version); }
void load(int to_version) { t_.load(to_version); }
T t_;
};
std::unique_ptr<Concept> t_;
};
The technique is similar to std::function, and now you probably also can see how type erasure uses polymorphism under the hood. You can see how it is used here.

How to self-document a callback function that is called by template library class?

I have a function User::func()(callback) that would be called by a template class (Library<T>).
In the first iteration of development, everyone know that func() serves only for that single purpose.
A few months later, most members forget what func() is for.
After some heavy refactoring, the func() is sometimes deleted by some coders.
At first, I didn't think this is a problem at all.
However, after I re-encountered this pattern several times, I think I need some counter-measure.
Question
How to document it elegantly? (cute && concise && no additional CPU cost)
Example
Here is a simplified code:-
(The real world problem is scattering around 10+ library-files & 20+ user files & 40+ functions.)
Library.h
template<class T> class Library{
public: T* node=nullptr;
public: void utility(){
node->func(); //#1
}
};
User.h
class User{
public: void func(){/** some code*/} //#1
//... a lot of other functions ...
// some of them are also callback of other libraries
};
main.cpp
int main(){
Library<User> li; .... ; li.utility();
}
My poor solutions
1. Comment / doc
As the first workaround, I tend to add a comment like this:-
class User{
/** This function is for "Library" callback */
public: void func(){/** some code*/}
};
But it gets dirty pretty fast - I have to add it to every "func" in every class.
2. Rename the "func()"
In real case, I tend to prefix function name like this:-
class User{
public: void LIBRARY_func(){/** some code*/}
};
It is very noticeable, but the function name is now very longer.
(especially when Library-class has longer class name)
3. Virtual class with "func()=0"
I am considering to create an abstract class as interface for the callback.
class LibraryCallback{
public: virtual void func()=0;
};
class User : public LibraryCallback{
public: virtual void func(){/** some code*/}
};
It provides feeling that func() is for something-quite-external. :)
However, I have to sacrifice virtual-calling cost (v-table).
In performance-critical cases, I can't afford it.
4. Static function
(idea from Daniel Jour in comment, thank!)
Almost 1 month later, here is how I use :-
Library.h
template<class T> class Library{
public: T* node=nullptr;
public: void utility(){
T::func(node); //#1
}
};
User.h
class User{
public: static void func(Callback*){/** some code*/}
};
main.cpp
int main(){
Library<User> li;
}
It is probably cleaner, but still lack self-document.
func is not a feature of User. It is a feature of the User-Library<T> coupling.
Placing it in User if it doesn't have clear semantics outside of Library<T> use is a bad idea. If it does have clear semantics, it should say what it does, and deleting it should be an obviously bad idea.
Placing it in Library<T> cannot work, because its behavior is a function of the T in Library<T>.
The answer is to place it in neither spot.
template<class T> struct tag_t{ using type=T; constexpr tag_t(){} };
template<class T> constexpr tag_t<T> tag{};
Now in Library.h:
struct ForLibrary;
template<class T> class Library{
public: T* node=nullptr;
public: void utility(){
func( tag<ForLibrary>, node ); // #1
}
};
in User.h:
struct ForLibrary;
class User{
/** This function is for "Library" callback */
public:
friend void func( tag_t<ForLibrary>, User* self ) {
// code
}
};
or just put this into the same namespace as User, or the same namespace as ForLibrary:
friend func( tag_t<ForLibrary>, User* self );
Before deleting func, you'll track down ForLibrary.
It is no longer part of the "public interface" of User, so doesn't clutter it up. It is either a friend (a helper), or a free function in the same namespace of either User or Library.
You can implement it where you need a Library<User> instead of in User.h or Library.h, especially if it just uses public interfaces of User.
The techniques used here are "tag dispatching", "argument dependent lookup", "friend functions" and preferring free functions over methods.
From the user side, I would use crtp to create a callback interface, and force Users to use it. For example:
template <typename T>
struct ICallbacks
{
void foo()
{
static_cast<T*>(this)->foo();
}
};
Users should inherit from this interface and implement foo() callback
struct User : public ICallbacks<User>
{
void foo() {std::cout << "User call back" << std::endl;}
};
The nice thing about it is that if Library is using ICallback interface and User forget to implement foo() you will get a nice compiler error message.
Note that there is no virtual function, so no performance penalty here.
From the library side, I would only call those callbacks via its interfaces (in this case ICallback). Following OP in using pointers, I would do something like this:
template <typename T>
struct Library
{
ICallbacks<T> *node = 0;
void utility()
{
assert(node != nullptr);
node->foo();
}
};
Note that things get auto documented in this way. It is very explicit that you are using a callback interface, and node is the object who has those functions.
Bellow a complete working example:
#include <iostream>
#include <cassert>
template <typename T>
struct ICallbacks
{
void foo()
{
static_cast<T*>(this)->foo();
}
};
struct User : public ICallbacks<User>
{
void foo() {std::cout << "User call back" << std::endl;}
};
template <typename T>
struct Library
{
ICallbacks<T> *node = 0;
void utility()
{
assert(node != nullptr);
node->foo();
}
};
int main()
{
User user;
Library<User> l;
l.node = &user;
l.utility();
}
Test.h
#ifndef TEST_H
#define TEST_H
// User Class Prototype Declarations
class User;
// Templated Wrapper Class To Contain Callback Functions
// User Will Inherit From This Using Their Own Class As This
// Class's Template Parameter
template <class T>
class Wrapper {
public:
// Function Template For Callback Methods.
template<class U>
auto Callback(...) {};
};
// Templated Library Class Defaulted To User With The Utility Function
// That Provides The Invoking Of The Call Back Method
template<class T = User>
class Library {
public:
T* node = nullptr;
void utility() {
T::Callback(node);
}
};
// User Class Inherited From Wrapper Class Using Itself As Wrapper's Template Parameter.
// Call Back Method In User Is A Static Method And Takes A class Wrapper* Declaration As
// Its Parameter
class User : public Wrapper<User> {
public:
static void Callback( class Wrapper* ) { std::cout << "Callback was called.\n"; }
};
#endif // TEST_H
main.cpp
#include "Test.h"
int main() {
Library<User> l;
l.utility();
return 0;
}
Output
Callback was called.
I was able to compile, build and run this without error in VS2017 CE on Windows 7 - 64bit Intel Core 2 Quad Extreme.
Any Thoughts?
I would recommend to name the wrapper class appropriately, then for each specific call back function that has a unique purpose name them accordingly within the wrapper class.
Edit
After playing around with this "template magic" well there is no such thing...
I had commented out the function template in the Wrapper class and found that it is not needed. Then I commented out the class Wrapper* that is the argument list for the Callback() in User. This gave me a compiler error that stated that User::Callback() does not take 0 arguments. So I looked back at Wrapper since User inherits from it. Well at this point Wrapper is an empty class template.
This lead me to look at Library. Library has a pointer to User as a public member and a utility() function that invokes User's static Callback method. It is here that the invoking method is taking a pointer to a User object as its parameter. So it lead me to try this:
class User; // Prototype
class A{}; // Empty Class
template<class T = User>
class Library {
public:
T* node = nullptr;
void utility() {
T::Callback(node);
}
};
class User : public A {
public:
static void Callback( A* ) { std::cout << "Callback was called.\n"; }
};
And this compiles and builds correctly as the simplified version. However; when I thought about it; the template version is better because it is deduced at compile time and not run time. So when we go back to using templates javaLover had asked me what class Wrapper* means or is within the argument list for the Callback method within the User class.
I'll try to explain this as clearly as I can but first the wrapper Class is just an empty template shell that User will inherit from and it does nothing but act as a base class and it now looks like this:
template<class T>
class Wrapper { // Could Be Changed To A More Suitable Name Such As Shell or BaseShell
};
When we look at the User class:
class User : public Wrapper<User> {
public:
static void Callback( class Wrapper* ) { // print statement }
};
We see that User is a non-template class that inherits from a template class but uses itself as the template's argument. It contains a public static method
and this method doesn't return any thing but it does take a single parameter; this is also evident in the Library class that has its template parameter as a User class. When the Library's utility() method invokes User's Callback() method the parameter that the Library is expecting is a pointer to a User object. So when we go back to the User class instead of declaring it as a User* pointer directly in its declaration I'm using the empty class template that it inherits from. However if you try to do this:
class User : public Wrapper<User> {
public:
static void Callback( Wrapper* ) { // print statement }
};
You should get a message that Wrapper* is missing it's argument list. We could just do Wrapper<User>* here but that is redundant since we already see that User is inheriting from Wrapper that takes itself. So we can fix this and make it cleaner just by prefixing the Wrapper* with the class keyword since it is a class template. Hence the template magic... well there is no magic here... just compiler intrinsic and optimizations.
While I know that I don't answer your specific question (how to document the not-to-be-deleted function) I would solve your problem (keeping the seemingly unused callback function in the code base) by instantiating Library<User> and calling the utility() function in a unit test (or maybe it should rather be called an API test...). This solution would probably scale to your real world example too, as long as you don't have to check each possible combination of library classes and callback functions.
If you are lucky enough to work in an organization where successful unit tests and code review are required before changes go into the code base this would require a change to the unit tests before anyone could remove the User::func() function and such a change would probably catch the attention of a reviewer.
Then again, you know your environment and I don't, and I'm aware that this solution doesn't fit all situations.
Here is a solution using a Traits class:
// Library.h:
template<class T> struct LibraryTraits; // must be implemented for every User-class
template<class T> class Library {
public:
T* node=nullptr;
void utility() {
LibraryTraits<T>::func(node);
}
};
// User.h:
class User { };
// must only be implemented if User is to be used by Library (and can be implemented somewhere else)
template<> struct LibraryTraits<User> {
static void func(User* node) { std::cout << "LibraryTraits<User>::func(" << node << ")\n"; }
};
// main.cpp:
int main() {
Library<User> li; li.utility();
}
Advantages:
It is obvious by the naming that LibraryTraits<User> is only required for interfacing User by Library (and can be removed, once either Library or User gets removed.
LibraryTraits can be specialized independent of Library and User
Disadvantages:
No easy access to private members of User (making LibraryTraits a friend of User would remove the independence).
If the same func is needed for different Library classes multiple Trait classes need to be implemented (could be solved by default implementations inheriting from other Trait classes).
This heavily reminds an old good Policy-Based Design, except in your case you do not inherit the Library class from the User class.
Good names are the best friends of any API. Combine this and the well-known patter of Policy-Based Design (well-known is very important because the class names with the word Policy in it will immediately ring the bell in many readers of the code) and, I assume, you get a well self-documenting code.
Inheritance won't give you any performance overhead, but will give you an ability to have the Callback as a protected method, that will give some hint that it is supposed to be inherited and be used somewhere.
Have clearly standing-out and consistent naming among multiple User-like classes (e.g. SomePolicyOfSomething in the manner of aforementioned Policy-Based Design), as well as, the template arguments for the Library (e.g SomePolicy, or I would call it TSomePolicy).
Having using declaration of the Callback in the Library class might give much clearer and earlier errors (e.g. from IDE, or modern clang, visial studio syntax parsers for IDE).
Another arguable option might be a static_assert if you have C++>=11. But in this case it must be used in every User-like class ((.
Not a direct answer to your question on how to document it, but something to consider:
If your Library template requires an implementation of someFunction() for each class to be used in it, i'd recommend adding it as a template argument.
#include <functional>
template<class Type, std::function<void(Type*)> callback>
class Library {
// Some Stuff...
Type* node = nullptr;
public:
void utility() {
callback(this->node);
}
};
Might make it even more explicit, so that other devs know it's needed.
abstract class is the best way to enforce the function not to be deleted. So i recommend implementing the base class with pure virtual function, so that derived has to define the function.
OR second solution would be to have function pointers so that performance will be saved by avoiding extra overhead of V-table creation and calling.
If it is not obvious that func() is needed in User, then I'd argue you're violating the single responsibility principle. Instead create an adapter class of which User as a member.
class UserCallback {
public:
void func();
private:
User m_user;
}
That way the existance of UserCallback documents that func() is an external call back, and separates out Library's need of a callback from the actual responsibilities of User.

Method of one class as callback from another

I will describe my problem the simplest as I can.
What is my issue:
I have frist class as a singleton:
class CTimer1
{
public:
static CTimer1 * getInstance(); //This gives me pointer to instance
void setChannelA(uint8_t compareValue);
private:
//Cnstructors
CTimer1(); //Prevent consttuction but allow in getInstance
CTimer1(const CTimer1&); //Prevent construction by copying
CTimer1& operator=(const CTimer1&); //Prevent assigment
~CTimer1(); //Prevent unwanted destruction
static CTimer1 * timerInstance;
static bool isCreated;
};
And here is second class where I would like to have possibility to call setChannelA method from CTimer1 class as a setPwm method from CServo class:
class CServo {
public:
CServo();
~CServo();
public:
//public methods
void registerPwmTimer(void (*callback)(uint8_t u8_buffer));
void (*setPwm)(uint8_t u8_buffer); //As this method I would like to call setChannelA from CTimer1 class
};
Here is registerPwmTimer method:
void CServo::registerPwmTimer(void (*callback)(uint8_t u8_buffer))
{
setPwm = callback;
}
Then I have tried to assign pointer to this method as a following:
int main()
{
CTimer1 * timer1 = CTimer1::getInstance();
CServo servo1();
servo1.registerPwmTimer(timer1->setChannelA);
servo1.setPwm(10); //This is example how I want to call setChannelA method
while(1)
{
}
}
I have error:
error: no matching function for call to 'CServo::registerPwmTimer(<unresolved overloaded function type>)'
What is important:
I can't use std::function because this is some part of code in C++ for embedded device, so I need to save memory consumption. Is there any way that I will be able to achieve this effect? If ony one possibility to do this is ot use some std library please for answers too. Thanks for your help.
Your problem is that a function pointer necessarily has to point to a static function. When you invoke an instance function (a method) there is a hidden first argument, which is the object on which the function was invoked. (This hidden argument is available as this within the function's definition.)
Your CServo::registerPwmTimer() function signature is simply incompatible with invocation of a member function; function pointers alone do not provide a way to bind an argument to the pointer, so even if you could convey the member function pointer using a (free) function pointer type, the hidden this argument could not be determined when the function pointer was invoked.
To put it another way, it would fail for the same reason that trying CTimer1::setChannelA(0) would fail -- you want to invoke that method, but you haven't communicated which object on which to invoke it.
Change the signature of CServo::registerPwmTimer to accept an std::function object instead of a raw function pointer. std::function objects can be constructed from function pointers, but they can also be constructed from lambdas, and some standard library functions return function objects:
void registerPwmTimer(std::function<void(uint8_t)>);
Now, you can use std::bind to create a new function that binds the object instance to the member function pointer:
servo1.registerPwmTimer(std::bind(&CTimer1::setChannelA, timer1));
Note that std::bind does not extend the lifetime of the object pointed to by timer1. If the returned function is invoked after that object is destructed, the result is undefined behavior.
Another alternative would be to accept both an instance and a pointer to a member function. The problem with this approach is it requires using templates:
template <typename T>
void registerPwmTimer(void (T::*)(uint8_t), T&);
This isn't bad in itself, but what you'll wind up doing is creating a polymorphic wrapper class so that you can insert this into your callback list alongside other callbacks that don't share the same T. At that point, you're just recreating std::function, since std::function already serves the purpose of being a polymorphic wrapper around callable things.
To illustrate the mess of implementing a polymorphic callable wrapper yourself, here is a very light example. I will show the declarations of a set of these types, and link to an example implementation.
This is the base type, with a pure virtual operator() that serves as the invocation operation.
class poly_callable
{
public:
virtual void operator()(int) const = 0;
};
Now we have a type for function pointers (also works with pointer-to-functor):
template <typename T>
class fn_poly_callable : public poly_callable
{
public:
typedef T fn_type;
fn_poly_callable(T);
virtual void operator()(int) const;
private:
T fn;
};
And one for member functions -- oh, but const member functions and non-const member functions are not interchangeable, so we need an extra template parameter for that:
template <typename T, typename M = void (T::*)(int)>
class member_poly_callable : public poly_callable
{
public:
typedef T object_type;
typedef M member_fn_type;
member_poly_callable(member_fn_type, object_type&);
virtual void operator()(int) const;
private:
member_fn_type mfn;
object_type& target;
};
Plus we'll want some helper functions to allow the compiler to infer the template types. One for function pointers:
template <typename T>
std::unique_ptr<poly_callable> make_poly_callable(T fn)
{
return std::unique_ptr<poly_callable>(new fn_poly_callable<T>(fn));
}
Two for member functions (const and non-const):
template <typename T>
std::unique_ptr<poly_callable> make_poly_callable(void (T::*mfn)(int), T& target)
{
return std::unique_ptr<poly_callable>(new member_poly_callable<T>(mfn, target));
}
template <typename T>
std::unique_ptr<poly_callable> make_poly_callable(void (T::*mfn)(int) const, T& target)
{
return std::unique_ptr<poly_callable>(new member_poly_callable<T, void (T::*)(int) const>(mfn, target));
}
If you want to see it all in action, I made a "simple" and working example.
So... just use std::function. There's no reason to reinvent this stuff.

Passing a Functor as a param to a method

I have the following two classes that exhibit the Command pattern. (Unfortunately, both have a unique method name.)
//pseudocode
class Subscriber {
virtual void receive(const Event&) = 0;
}
class Dispatcher {
virtual void dispatch(const Event&) = 0;
}
I have a class template that has a list of some type with a method to iterate over this list.
//pseudocode
template<typename T>
class Registry {
typedef list<T> ObjectList;
ObjectList _objects;
void iterate(const Event& event) {
for_each(_objects.begin(), _objects.end(), ...); //not sure what to do here
}
}
I would like to use mem_fun to create a Functor that calls receive or dispatch as appropriate. I'm able to create a simple use case where I simply invoke a method without any params. I.e.
//pseudocode
class Simple {
void simple() {/*...*/}
}
and then I iterate:
for_each(_objects.begin(), _objects.end(), mem_fun(&Simple::simple);
Unfortunately, I have no idea how to get the event param passed to mem_fun. Looking at the headers, it does appear that I can pass a single param, but I'm not well versed in C++ to understand what I need to do.
Ultimately, I would like to make the iterate method accept a type of functor so it will fire that method on every method in the list.
I would prefer to avoid Boost...I think this is entirely possible without dragging this framework into the mix.
Thanks!
This may be the most straight-forward way:
class event_forwarder // make private in Registry
{
public:
event_forwarder(const Event& event) :
mEvent(event)
{}
void operator()(Subscriber& subcriber) const
{
subscriber.receive(mEvent);
}
void operator()(Dispatcher& dispatcher) const
{
dispatcher.dispatch(mEvent);
}
private:
const Event& mEvent;
};
Then:
for_each(_objects.begin(), _objects.end(), event_forwarder(event));
If I understand correctly, what you want is std::bind2nd:
std::for_each(_objects.begin(), _objects.end(),
std::bind2nd(std::mem_fun_ref(&Subscriber::receive), event));
The member-function Subscriber::receive has two parameters. The first is the implicit this pointer, and the second the const Event &. std::bind2nd, given a function f taking two arguments, returns a function f_1 taking one argument, that invokes the original function f with a fixed value for the second argument.
Edit:
To handle the different names of the dispatch functions, you can make the dispatch function a template parameter:
//pseudocode
template<typename T, void (T::*dispatch_method)(Event)>
class Registry {
typedef list<T> ObjectList;
ObjectList _objects;
void iterate(const Event& event) {
std::for_each(_objects.begin(), _objects.end(),
std::bind2nd(std::mem_fun_ref(dispatch_method), event));
}
}
Unfortunately, there does not seem to be a way to make bind2nd handle const reference parameters, so my whole solution is moot, unless copying Event objects is fine with you. This will work in C++0x with std::bind though, and the idea of making the dispatch function a template parameter is still valid. You can even use traits, to make that mechanism even more flexible.
You could create a functor class that wraps your Subscriber and Dispatcher classes, e.g.
class MyFunctor {
public:
virtual void Execute(const Event& event) = 0;
};
class MySubscriberFunctor : public MyFunctor {
private:
Subscriber subscriber_;
public:
void Execute(const Event& event) {
subscriber_.receive(event);
}
};
class MyDispatcherFunctor : public MyFunctor {
private:
Dispatcher dispatcher_;
public:
void Execute(const Event& event) {
dispatcher_.dispatch(event);
}
};
Your object list could then store these functor wrappers as a list of MyFunctor instances. This way you can call Execute() on them and let them delegate to the underlying classes. You should really have an operator() instead of Execute() to get a "real" functor, but you get the idea.
Cheers
Check if you have tr1. If you have tr1, it contains std::bind, which is almost exactly equivalent to the boost implementation. This should be found in the <functional> header.
If you don't have tr1, consider using Boost. I would strongly suggest using at least boost::bind, as it's lightweight and header only.
If you don't have tr1 and won't use Boost, you want to mix bind2nd and mem_fun1. The first binds the second parameter (in this case, your event; the object will be the first) and mem_fun1 is the same as mem_fun, but it expects two arguments, the object to be called on and one parameter to pass the member function being called. This is a complete mess, though.
If you do have access to bind, it's fairly easy.
for_each(objects.begin(), objects.end(), bind(&Simple::simple, _1, event))

Passing objects of different types with the same interface

I have a number of class, all with exactly the same interface. This interface defines a few methods, some of which are templated (the class itself may or may not be).
So the interface looks something like this
class MyClass
{
public:
void Func1();
template <typename T>
void Func2(T param);
};
I have a number of functions which take various objects which conform to this interface but want to avoid having to know the exact implementation at compile time.
Obviously, the default C++ solution would be to have a base type that all these classes derive from and pass around a pointer to that and have polymorphism do all the work.
The problem is that templated member functions cannot be virtual so this method cannot be used. I also want to avoid changing the current set of classes that follow this interface because there are a large number of them, some of which are defined outside the scope of my project.
The other solution is to template the functions that use these objects so they specialise for the right type. This could be a solution but due to legacy requirements templating a large number functions may not be possible (this is something I cannot do anything about as the client code isn't something I have responsibility for).
My initial thought was to provide some kind of carrier class which is type neutral and in effects wraps the common interface here and has a base interface class to pass around the internal type.
Something along the lines of
class MyInterface
{
public:
virtual void Func1() = 0;
};
template <typename T>
class MyImplementation
{
public:
virtual void Func1()
{
m_impl->Func1();
}
private:
T* m_impl;
};
But again the templated member functions seem to block this approach.
I looked at the boost::any and boost::function classes which I thought might offer some kind of solution but they don't seem to give me the right answer.
So, does anyone have any suggestions or work around on how to make this possible, if indeed it is? Personally I'm leaning towards having to template the various functions that require these objects - since that's the functionality templates provide - but thought it worth investigating first.
Thanks in advance
What's not entirely clear to me is how you're resolving the parameter T to Func2, do you need some kind of dynamic dispatch on that too, or is it known at compile time at the call site?
In the former case, it sounds like multimethods. In the latter, how about this variation on your interface idea:
#include <iostream>
template<class T> struct generic_delegate
{
virtual void call(T param) = 0;
};
template<class U, class T> class fn_delegate : public generic_delegate<T>
{
U* obj;
void (U::*fn)(T);
public:
fn_delegate(U* o, void (U::*f)(T)) :
obj(o), fn(f)
{}
virtual void call(T param)
{
(obj->*fn)(param);
}
};
class A
{
public:
template<class T> void fn(T param)
{
std::cout << "A: " << param << std::endl;
}
};
class B
{
public:
template<class T> void fn(T param)
{
std::cout << "B: " << param << std::endl;
}
};
template<class T, class U> generic_delegate<T>* fn_deleg(U* o)
{
return new fn_delegate<U, T>(o, &U::template fn<T>);
}
int main()
{
A a;
B b;
generic_delegate<int>* i = fn_deleg<int>(&a);
generic_delegate<int>* j = fn_deleg<int>(&b);
i->call(4);
j->call(5);
}
Obviously, the thing you'd be passing around are the generic delegate pointers.
If you use templates you need to know AT COMPILE TIME which type(s) you're using. That's just the nature of templates (templates look like code that's dynamic at runtime, but in reality it's just shorthand that tells the compiler what versions of the function to compile and include in the object code). Best case senario is something like this:
template <class T>
void DoSomethingWithMyInterface(MyInterface<T> X)
{
//do something
}
...
switch (MyObject.GetTypeCode())
{
case TYPE1: DoSomethingWithMyInterface<type1>(MyObject); break;
case TYPE2: DoSomethingWithMyInterface<type2>(MyObject); break;
case TYPE3: DoSomethingWithMyInterface<type3>(MyObject); break;
case TYPE4: DoSomethingWithMyInterface<type4>(MyObject); break;
}
I actually use this situation a lot. I write templated c++ code that does the processing for a dynamically typed language. That means that the top level language doesn't know the data types until run time, but I need to know them at compile time. So I create this "TypeSwitch" (I actually have a fancy reusable one). That looks at the datatypes at run time and then figures out which of the already compiled template functions to run.
Note - that this requires me knowing all the types I'm going to support before hand (and I do) and the switch statement actually causes the compiler to generate all of the code that could ever be executed. Then at runtime the right one is selected.