class Action {
public:
void operator() () const;
}
class Data {
public:
Data();
~Data();
Register(Action action) { _a = action; }
private:
Action _a;
}
class Display {
public:
Display(Data d) { d.Register( bind(Display::SomeTask, this, _1) ); }
~Display();
void SomeTask();
}
I want to bind the private member _a of Data to a member function of Display, but I get compile errors saying my argument types don't match when I call d.Register, what am I doing wrong? Thanks.
What you're trying to do is not completely clear, but I'll assume that "bind" is boost::bind (or tr1::bind).
A couple of problems with bind(Display::SomeTask, this, _1):
It should be &Display::SomeTask
The _1 placeholder makes no sense because that creates an unary function object and:
Display::SomeTask takes no arguments
Action::operator() takes no arguments
Using Boost.Function and Boost.Bind, here's what you could write to acheive what I guess you're trying to do:
typedef boost::function<void(void)> Action;
class Data {
public:
Data();
~Data();
Register(Action action) { _a = action; }
private:
Action _a;
};
class Display {
public:
Display(Data d) { d.Register( bind(&Display::SomeTask, this) ); }
~Display();
void SomeTask();
};
I cannot see what 'bind' returns, but I absolutely sure this is not compatible with Action class. Also you are using 'copy semantic', so if Action has empty implmentation, you will never get desired.
Try change Register(Action* action), and allow 'bind' to return some child of Action class.
Also review possibility to migrate to templates - than you even can exclude Action class at all
template <class A>
class Data { ...
Register(A action)...
A _a;
...
In this case you could be able to use as classes with overridden operator() as functions without argument.
First, you have to use &Display::SomeTask and give Register a return type, and then it depends on your needs
The wrapper should call SomeTask on *this: Omit _1.
The wrapper should call SomeTask on a passed Display object: Shift _1 in place of this.
Then, boost::bind returns some complicated synthesized type that will call the specified function. You need a way to store it, which is where boost::function comes handy. This is how you can do it
class Display; // forward-declaration
class Data {
public:
Data();
~Data();
template<typename Action>
void Register(Action action) { _a = action; }
private:
boost::function<void(Display&)> _a;
// if wrapper should call it on `*this`
// boost::function<void()> _a;
}
class Display {
public:
// this currently makes no sense. You pass a copy. Probably you
// should consider pass-by-reference or processing "d" further.
Display(Data d) { d.Register( bind(&Display::SomeTask, _1) ); }
// wrapper should call it on `*this`:
// Display(Data d) { d.Register( bind(&Display::SomeTask, this) ); }
~Display();
void SomeTask();
}
Then it should work.
Related
Is it possible to be able to assign a "flexible" type to a class member? This would be somewhat like std::variant or std::any, except std::variant requires types to be stated in advance and std::any requires any_cast<Type> (which isn't a problem, except for saving the type information so I'd know what type to cast the std::any member to).
What I'm looking for is something that makes the following functionality possible:
class FlexType
{
ChangeableType m_Value;
public:
FlexType(SomeType init_value)
: m_Value(init_value)
{}
void setValue(SomeOtherType new_value) { m_Value = new_value; }
CurrentType getValue() const { return m_Value; }
};
Edit
I need the functionality for storing a return type of an std::function, where I want to be able to change the std::function's return type to any given type. This comes from a class that has a virtual void run() const method (call it "ParentClass" for convenience). I then have a child class that overrides the run() method and runs an std::function and saves the return value in another class member.
It looks something like this:
class ParentClass
{ // Example basic parent class
private:
/* ... Class members ... */
public:
ParentClass() = default;
virtual void run() const { /* Do stuff w/ class members */ }
};
template<class FuncRetTy, class... FuncArgs>
class ChildClass : public ParentClass
{
private:
using function_return_type = FuncRetTy;
using function_arg_types = FuncArgs...;
using function_args_container = std::tuple<function_arg_types>;
std::function<function_return_type(function_args_container)>
mutable function_return_type m_StoredValue;
function_type m_Function;
func_args_container m_Args;
public:
FunctionMenu(
function_return_type type_var, // Used to deduce return type
function_type function,
function_arg_types arguments)
: m_Function(function)
, m_Args(std::make_tuple(std::forward<FuncArgs>(arguments)...))
{}
void run() const override
{
m_StoredValue = m_Function(m_Args);
}
[[nodiscard]] function_return_type getStoredValue() const
{
return m_StoredValue;
}
// This is where my problem is...
// I want to be able to set m_Function to another function,
// but this means the return type can change, and so can
// the tuple template parameters for m_Args.
// The below code is just pseudocode
template<class NewFuncRetTy, class... NewFuncArgs>
void setFunction(
NewFuncRetTy type_var,
std::function<NewFuncRetTy(std::tuple<NewFuncArgs...>)> function
NewFuncArgs... args)
{
// Change all class typedef's to new types
// Reassign m_Function = function
// Reassign m_Args = make_tuple(std::forward<NewFuncArgs>(args)...);
// Delete whatever value m_StoredValue already has and
// change type of m_StoredValue to NewFuncRetTy so
// getStoredValue() knows what type to return
}
};
I'm sorry about there being a lot of code, but I figured explaining in detail what exactly I'm asking for would help people understand the question better.
I'm having a great deal of problems trying to make a callback system. I want to pass a function to another class's function to receive data.
I want ExampleClass to call SeperateThread::operate, and I want SeperateThread::operate to be able to call ExampleClass::updateNumber(int) to return a value. I've been trying for hours with various function pointers etc but can't seem to get it to work.
SeperateThread is another thread so it doesn't block the main thread that ExampleClass is running in, but when SeperateThread has done it's calculations, I need to return the value to ExampleClass.
If that makes sense? Here's a run down of what I'm trying to do. In this example, I want SeperateThread::operate to call ExampleClass::updatenumber(15);...
class ExampleClass
{
public:
ExampleClass()
{
int numberToPass = 10;
// call SeperateThread::operate and pass value and updatenumber function as pointer
thread.operate(numberToPass, *updatenumber(int number));
}
~ExampleClass();
void updatenumber(int number)
{
// Do some stuff to the number passed to this function
}
private:
SeperateThread thread;
}
class SeperateThread
{
public:
SeperateThread();
~SeperateThread();
void operate(int number, &FunctionToCallBack)
{
// Do some calculations (result 5 for example purposes)
int result = numberToPass + 5;
// Call the callback function and pass result int
FunctionToCallBack(result);
}
}
There are two issues here:
1. A Callback Function Is Not Enough
You'll need both an address for the code to call back, and the identity of the object on which the code should operate. The idiomatic C++ way to do this is to encapsulate this in an object:
class SeparateThread {
public:
class Callback {
public:
virtual void ThreadDone(int result) const = 0;
virtual ~Callback() {}
};
void operate(int number, const Callback & callback)
{
// Calculate result
callback.ThreadDone(result);
}
};
ExampleClass can then either inherit privately from SeparateThread::Callback and implement ThreadDone() or define a separate callback class:
class ExampleClassThreadCallback : public SeparateThread::Callback {
public:
ExampleClassThreadCallback(ExampleClass * obj) : fObj(obj) {}
void ThreadDone(int result) const override {
fObj.updatenumber(result);
private:
ExampleClass * fObj;
}
};
You then simply call the thread as:
thread.operate(number, ExampleClassThreadCallback(this));
2. Concurrency
In a design like this, where your class gets updated from a separate thread, you are likely to run into concurrency issues, so you'll have to design appropriate mechanisms to make sure that this updating does not cause problems.
There is something important about pointing to a class member function, you have to keep in mind that a function pointer is just a regular pointer but instead of a value it points to a function, but in a class there is a special hidden variable this which makes it tricky.
One of the main problems here is that there is no pointer to the object since that would mean that you point to a function that exists within a specific object but it doesn't it just a plain function that contains this as a parameter.
thread.operate(numberToPass, *updatenumber(int number));
Here you call a function that is in another class and overall you never pass a pointer like this, it should be just the function's name since C will recognize that you want to pass it as a pointer. Generally the workaround would be to make the function static to avoid the problem with the this pointer.
One possible workaround would be to hold onto the class object and somehow hackishly call that function where you manually pass the this of the original object ( ExampleClass ).
You didn't say much about your design, but the fact that you put the source into the same field means that these classes "know" each other so why don't you just pass the class object and call the function that way like:
class BaseClass
{
public:
BaseClass() {}
~BaseClass() {}
virtual void updatenumber(int number)=0; // pure virutal method, you MUST implement this in the subclasses!
}
class ExampleClass : public BaseClass
{
public:
ExampleClass()
{
int numberToPass = 10;
// call SeperateThread::operate and pass value and updatenumber function as pointer
thread.operate(numberToPass, this);
}
~ExampleClass();
// this is now a virtual method
void updatenumber(int number)
{
// Do some stuff to the number passed to this function
}
private:
SeperateThread thread;
}
class SeperateThread
{
public:
SeperateThread();
~SeperateThread();
void operate(int number,BaseClass* ObjectToCallBack)
{
// Do some calculations (result 5 for example purposes)
int result = numberToPass + 5;
// Call the callback function and pass result int
// Note that here that this points to the BaseClass pointer but it can be a subclass of it effectively hiding it's "unneded members" at this specific point
ObjectToCallBack->updatenumber(result);
}
}
In case you want to hide the implementation you can just use a pure virtual class and pass that type of pointer to the SeperateThread class.
Edit : updated my example to use a base class.
There is a way to pass a member of a specific class instance to another function whether in a thread or not. If the callback is a member you need to wrap it together with the class instance you want the callback to affect.
template<typename T, typename F, typename R>
struct callback
{
callback(T cthis, F func) : _this(cthis), _func(func) { }
void operator()(R result)
{
(_this->*_func)(result);
}
T _this;
F _func;
};
class SeperateThread
{
public:
SeperateThread() { }
~SeperateThread() { }
template<typename T, typename F, typename R>
void operate(int number, callback<T,F,R> cb)
{
// Do some calculations (result 5 for example purposes)
int result = number + 5;
// Call the callback function and pass result int
cb(result);
}
};
class ExampleClass
{
public:
ExampleClass()
{
int numberToPass = 10;
// call SeperateThread::operate and pass value and updatenumber function as pointer
thread.operate(numberToPass, callback<ExampleClass * const, void (ExampleClass::*)(int), int>(this, &ExampleClass::updatenumber) );
}
~ExampleClass() { }
void updatenumber(int number)
{
// Do some stuff to the number passed to this function
printf("Result is %d\n", number);
}
private:
SeperateThread thread;
};
void test()
{
ExampleClass a;
}
The above will print: Result is 15.
Please note that I did not address the synchronization issues due to multithreading.
If 'updatenumber' is called by more than one thread, and your code inside it accesses other data members, then you need to serialize it by adding a mutex lock at the beginning and unlock it before returning. Best is to use std::mutex if you have C++11 compiler, or do this within a small struct, locking in the constructor and unlocking in the destructor. Then you just create one such instance immediately on updatenumber() entry.
I have a question regarding callbacks using tr1::function. I've defined the following:
class SomeClass {
public:
typedef std::tr1::function<void(unsigned char*, int)> Callback;
void registerCallback(Callback);
private:
Callback callback;
}
I've defined another class:
class SomeOtherClass {
void myCallback(unsigned char*, int);
}
Now I want to register my function 'myCallback' as callback at class 'SomeClass'using the method 'registerCallback'. However, it is not working. I've had a look on the boost documentation on the function and it seems legit to use (member) methods of a class for callbacks. Am I wrong?
Thanks in advance!
Member functions have an implicit first parameter, a this pointer so as to know which object to call the function on. Normally, it's hidden from you, but to bind a member function to std::function, you need to explicitly provide the class type in template parameter.
#include <functional>
#include <iostream>
struct Callback_t {
void myCallback(int)
{
std::cout << "You called me?";
}
};
class SomeClass {
public:
SomeClass() : callback() { }
typedef std::function<void(Callback_t*, int)> Callback;
// ^^^^^^^^^^^
void registerCallback(const Callback& c)
{
callback = c;
}
void callOn(Callback_t* p)
{
callback(p, 42);
}
private:
Callback callback;
};
int main()
{
SomeClass sc;
sc.registerCallback(&Callback_t::myCallback);
Callback_t cb; // we need an instance of Callback_t to call a member on
sc.callOn(&cb);
}
Output: You called me?;
Why all this complicated mumbo-jumbo?
Why not create a class as thus (for example)
Class MouseOverEventCallBack
{
public:
virtual void RunMouseOverCallback() = 0;
};
Then just create classes that inherit this class (and redefine the method RunMouseOverCallback)
Then Register function just needs to be
void registerCallback(MouseOverEventCallBack *callbackObject); // possible could use a reference
The register method will just call the method and the object will have all that it needs.
Seems a bit simpler. Let the compiler do the work with pointers to functions etc.
the function void (*)(unsigned char*, int) is a free function, which is a different type from void (SomeOtherClass::*)(unsigned char*, int), thus the error. You need an object to call the latter, while the former is a free function.
Look at the possible solutions listed in the Boost documentation
Another possibility is that your SomeOtherClass::myCallback is private, so you do not have access to it.
Use templates:
template <class T>
class B
{
public:
typedef void (T::*TCallBackFunction)(void);
void SetCallBack(T* pCallBackClass, TCallBackFunction pCallBackFunction)
{
if(pCallBackFunction && pCallBackClass)
{
m_pCallBackFunction = pCallBackFunction;
m_pCallBackClass = pCallBackClass;
}
}
void StartCallBackFunction()
{
(pCallBackClass->(*m_pCallBackFunction))();
}
private:
TCallBackFunction m_pCallBackFunction;
T* m_pCallBackClass;
};
Such like this. And use it:
...
B<MyClass> b;
b.SetCallBack(&b, &MyClass::MyFunction);
...
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;
Is there some library that allows me to easily and conveniently create Object-Oriented callbacks in c++?
the language Eiffel for example has the concept of "agents" which more or less work like this:
class Foo{
public:
Bar* bar;
Foo(){
bar = new Bar();
bar->publisher.extend(agent say(?,"Hi from Foo!", ?));
bar->invokeCallback();
}
say(string strA, string strB, int number){
print(strA + " " + strB + " " + number.out);
}
}
class Bar{
public:
ActionSequence<string, int> publisher;
Bar(){}
invokeCallback(){
publisher.call("Hi from Bar!", 3);
}
}
output will be:
Hi from Bar! 3 Hi from Foo!
So - the agent allows to to capsule a memberfunction into an object, give it along some predefined calling parameters (Hi from Foo), specify the open parameters (?), and pass it to some other object which can then invoke it later.
Since c++ doesn't allow to create function pointers on non-static member functions, it seems not that trivial to implement something as easy to use in c++. i found some articles with google on object oriented callbacks in c++, however, actually i'm looking for some library or header files i simply can import which allow me to use some similarily elegant syntax.
Anyone has some tips for me?
Thanks!
The most OO way to use Callbacks in C++ is to call a function of an interface and then pass an implementation of that interface.
#include <iostream>
class Interface
{
public:
virtual void callback() = 0;
};
class Impl : public Interface
{
public:
virtual void callback() { std::cout << "Hi from Impl\n"; }
};
class User
{
public:
User(Interface& newCallback) : myCallback(newCallback) { }
void DoSomething() { myCallback.callback(); }
private:
Interface& myCallback;
};
int main()
{
Impl cb;
User user(cb);
user.DoSomething();
}
People typically use one of several patterns:
Inheritance. That is, you define an abstract class which contains the callback. Then you take a pointer/reference to it. That means that anyone can inherit and provide this callback.
class Foo {
virtual void MyCallback(...) = 0;
virtual ~Foo();
};
class Base {
std::auto_ptr<Foo> ptr;
void something(...) {
ptr->MyCallback(...);
}
Base& SetCallback(Foo* newfoo) { ptr = newfoo; return *this; }
Foo* GetCallback() { return ptr; }
};
Inheritance again. That is, your root class is abstract, and the user inherits from it and defines the callbacks, rather than having a concrete class and dedicated callback objects.
class Foo {
virtual void MyCallback(...) = 0;
...
};
class RealFoo : Foo {
virtual void MyCallback(...) { ... }
};
Even more inheritance- static. This way, you can use templates to change the behaviour of an object. It's similar to the second option but works at compile time instead of at run time, which can yield various benefits and downsides, depending on the context.
template<typename T> class Foo {
void MyCallback(...) {
T::MyCallback(...);
}
};
class RealFoo : Foo<RealFoo> {
void MyCallback(...) {
...
}
};
You can take and use member function pointers or regular function pointers
class Foo {
void (*callback)(...);
void something(...) { callback(...); }
Foo& SetCallback( void(*newcallback)(...) ) { callback = newcallback; return *this; }
void (*)(...) GetCallback() { return callback; }
};
There are function objects- they overload operator(). You will want to use or write a functional wrapper- currently provided in std::/boost:: function, but I'll also demonstrate a simple one here. It's similar to the first concept, but hides the implementation and accepts a vast array of other solutions. I personally normally use this as my callback method of choice.
class Foo {
virtual ... Call(...) = 0;
virtual ~Foo();
};
class Base {
std::auto_ptr<Foo> callback;
template<typename T> Base& SetCallback(T t) {
struct NewFoo : Foo {
T t;
NewFoo(T newt) : t(newt) {}
... Call(...) { return t(...); }
};
callback = new NewFoo<T>(t);
return this;
}
Foo* GetCallback() { return callback; }
void dosomething() { callback->Call(...); }
};
The right solution mainly depends on the context. If you need to expose a C-style API then function pointers is the only way to go (remember void* for user arguments). If you need to vary at runtime (for example, exposing code in a precompiled library) then static inheritance can't be used here.
Just a quick note: I hand whipped up that code, so it won't be perfect (like access modifiers for functions, etc) and may have a couple of bugs in. It's an example.
C++ allows function pointers on member objects.
See here for more details.
You can also use boost.signals or boost.signals2 (depanding if your program is multithreaded or not).
There are various libraries that let you do that. Check out boost::function.
Or try your own simple implementation:
template <typename ClassType, typename Result>
class Functor
{
typedef typename Result (ClassType::*FunctionType)();
ClassType* obj;
FunctionType fn;
public:
Functor(ClassType& object, FunctionType method): obj(&object), fn(method) {}
Result Invoke()
{
return (*obj.*fn)();
}
Result operator()()
{
return Invoke();
}
};
Usage:
class A
{
int value;
public:
A(int v): value(v) {}
int getValue() { return value; }
};
int main()
{
A a(2);
Functor<A, int> fn(a, &A::getValue);
cout << fn();
}
Joining the idea of functors - use std::tr1::function and boost::bind to build the arguments into it before registering it.
There are many possibilities in C++, the issue generally being one of syntax.
You can use pointer to functions when you don't require state, but the syntax is really horrid. This can be combined with boost::bind for an even more... interesting... syntax (*)
I correct your false assumption, it is indeed feasible to have pointer to a member function, the syntax is just so awkward you'll run away (*)
You can use Functor objects, basically a Functor is an object which overloads the () operator, for example void Functor::operator()(int a) const;, because it's an object it has state and may derive from a common interface
You can simply create your own hierarchy, with a nicer name for the callback function if you don't want to go the operator overloading road
Finally, you can take advantage of C++0x facilities: std::function + the lambda functions are truly awesome when it comes to expressiveness.
I would appreciate a review on lambda syntax ;)
Foo foo;
std::function<void(std::string const&,int)> func =
[&foo](std::string const& s, int i) {
return foo.say(s,"Hi from Foo",i);
};
func("Hi from Bar", 2);
func("Hi from FooBar", 3);
Of course, func is only viable while foo is viable (scope issue), you could copy foo using [=foo] to indicate pass by value instead of pass by reference.
(*) Mandatory Tutorial on Function Pointers