I have read several posts about this, but can't seem to find exactly what i am looking for with example code if anyone could give me some help i would highly appreciate it.
in my header i have:
void addEvent(void (*func)(Pack *));
void triggerEvents(Pack * );
std::list<void(*)(Pack *)> eventList;
and in cpp file
void DNetwork::addEvent(void (*func)(Pack *)){
eventList.push_back(func);
}
void DNetwork::triggerEvents(Pack * pack){
for (std::list<void (*)( Pack *)>::iterator it = eventList.begin(); it != eventList.end() ;it++ ){
(*it)(pack);
}
}
This works fine with free functions, but when i try to add a member function to this list i get an error. Does anyone know how to store a member function (from random class objects) inside a pointer?
The simple solution is using type erasure on the function/function pointer type, for which the easier way is just using std::function<>:
std::list<std::function<void (Pack*)>;
Then you can initialize the function objects with either a free function or a member function (by means of std::bind to bind the member-function with an object on which to call it) or even function objects (types that offer an operator()).
For member function you need a bind. A member function is a "normal function" that has an implicit parameter of its class. So you need a binder. If you use c++11 you can use std::bind and std::function or you can use boost::bind and boost::function for non c++11 code.
typedef std::function< void ( Pack* ) > MyFunction;
void addEvent( MyFunction f );
void triggerEvents( Pack* );
std::list< MyFunction > eventList;
void DNetwork::addEvent( MyFunction f )
{
eventList.push_back( f );
}
void DNetwork::triggerEvents( Pack *pack )
{
for ( auto it = eventList.begin(); it != eventList.end(); it++ )
{
(*it)(pack);
}
}
Now if I have the class A with the method doA( Pack* ) I will write:
A a;
Pack pack;
DNetwork d;
d.addEvent( std::bind( &A::doA, &a, &pack ) );
Or even better you can use Boost.Signal or you can use the Publisher/Subcriber Pattern
Edit
As #DavidRodrÃguez-dribeas suggest: The bind should not take the &pack argument, as the argument to the member function is provided at the place of call in triggerEvents. The correct way is:
A a;
Pack pack;
DNetwork d;
d.addEvent( std::bind( &A::doA, &a, std::placeholders::_1 ) );
d.triggerEvents( &pack );
You could do an overload such as:
std::list<void(*)(Pack *)> eventList;
void addEvent(void (*func)(Pack *));
template<typename T>
void addEvent(void (T::*func)(Pack *));
namespace Abstraction {
template<typename T>
void abstractlyAddEvent( T, std::list<void(*)(Pack *)> *eventList );
}
If I'm understanding your problem you get the error when you try to add a function to the list in addEvent?
If you're adding a pointer to a non-static member function of a class ensure it has the right syntax... for example a function pointer to a a member function in TestClass would look like:
void * (TestClass:: *) ()
Related
I remember vaguely that python allowed something like
def foo( x ):
....
f = foo( 5 )
Is something like that possible in c++ so that if I have a member function
class C {
void foo( int x ) { ... }
so that I can define a pointer or variable that would effectively point at foo( 5 )
The reason why I want to do this is because I have many listeners that I need to subscribe to a callback and keep information who gets called
class C {
map<int, ptrSender> m_sender;
void subscribe() {
for (const auto& p : m_sender) {
p .second->register( Callback( this, &C::onCall ) )
}
My problem is that the onCall does not return which sender called back, but I would need this information. So, instead of doing something like this
void subscribe() {
m_sender[0]->register( Callback( this, onCall_0 ) );
m_sender[1]->register( Callback( this, onCall_1 ) );
....
void onCall( int sender_id ) { ... }
void onCall_0() { onCall( 0 ); }
void onCall_1() { onCall( 1 ); }
....
I was hoping I could pass something into register that would return a call with a preset argument. Is this possible?
EDIT: I am trying to use a lambda function, but I am running into the following problems
auto setCall= [this]( int v ) { &C::onCall( v ); }
gives the compile error
lvalue required as unary&opeand
This
auto setCall= [this]( int v ) { C::onCall( v ); }
....
p.second->register( Callback( this, &setCall( p.first) ) ); /// <__ error now here
complains again, now in the second line
lvalue required as unary&operand
and this
auto setCall= [this]( int v ) { C::onCall( v ); }
....
p.second->register( Callback( this, setCall( p.first) ) ); /// <__ error now here
complains about invalid use of void expression, but I assume I have to pass in a reference to make the register function happy
Callback seems to be defined as
# define CallBack(obj,func) ProfiledBasicCallBack(obj,fastdelegate::FastDelegate0<void>(obj,func),#func)
Yes, you can use std::bind. Example usage: http://ideone.com/akoWbA.
void foo( int x ) { cout << x << endl; }
auto x = std::bind(foo, 5);
x();
However, with modern C++, you should use a lambda. Like so:
void foo( int x ) { cout << x << endl; }
auto x = []() { foo(5); };
x();
Note that this foo function is outside of the class C in this example. If you wish to contain it inside, then with std::bind you need to pass the instance of the object you wish to call on, e.g.
C c;
auto x = std::bind(&C::foo, &c, 5);
x();
or with lambdas:
C c;
auto x = [&c]() { c.foo(5); };
x();
What you are looking for is std::bind(). It takes one callable object, and gives you another callable object with predefined values for its parameter, and maybe some optional parameters forwarded to it.
A word of warning: this is a fairly steep learning curve. You need to understand templates.
If you want to bind a parameter value to a compile-time constant argument (like 5 in your example), then the problem can be solved by introducing a simple wrapper function that will call your function while passing the desired constant values as corresponding arguments.
But when the argument is a run-time value, then the answer is no: it is generally not possible to create a credible implementation of such function pointer binding in C++ (unless you are using some compiler-specific extension).
However, in C++ you have a variety of alternative tools at your disposal. You can create a function object that will mimic the functionality you desire. Such function object can be created by using std::bind, by using lambda-expressions, or even implemented manually.
The resultant function object will be "callable" and will behave similarly to function pointer at superficial level, but nevertheless it won't be a function pointer, won't be convertible to a function pointer and won't be accepted where a genuine function pointer is required. In other words, if your register method is declared to expect a function pointer as its second argument, then there's nothing you can do here. Neither std::bind, nor lambdas, nor anything else in the language will help you to achieve this kind of parameter binding.
For this reason it is generally a good idea to steer clear of function pointers in such designs and implement such functionality in terms of generic callable objects. The simplest thing to use might be std::function objects in place of raw function pointers.
I am using boost v1.37 on MSVC7. I'm stuck on these old versions and cannot upgrade so please help me work within my means here and do not suggest upgrades as an answer.
I have a class with three member functions. I want to define a boost::function that can be used to call different member functions on different instances of the same class:
typedef boost::function<bool (unsigned, unsigned)> MyFunc;
The bind would look like:
boost::bind( &A::foo1, _1, _2, _3, boost::ref(some_fixed_param) );
I need to pass the boost::bind above into a function that takes a MyFunc as a parameter.
How do I need to setup my boost::function to take a function object (from boost::bind) that has the instance object set as a placeholder? How do pass the instance (this) into the boost::function? I keep getting compiler errors here so just trying to make sure I understand this properly. Hope I've explained clearly. Thanks in advance.
EDIT
The real error I get is:
sample.cpp(1156) : error C2664: 'process' : cannot convert parameter 2 from 'boost::_bi::bind_t<R,F,L>' to 'FooFunc &'
with
[
R=bool,
F=boost::_mfi::mf3<bool,A,unsigned int,unsigned int,int>,
L=boost::_bi::list4<boost::arg<1>,boost::arg<2>,boost::arg<3>,boost::reference_wrapper<int>>
]
The code I'm using:
typedef boost::function<bool (unsigned, unsigned)> FooFunc;
class A
{
public:
bool foo1( unsigned s1, unsigned s2, int s3 )
{
}
};
bool process( unsigned s1, FooFunc& foo )
{
unsigned s2 = 100;
A* a; // pretend this is valid
return foo( s1, s2 );
}
void dostuff()
{
int s3 = 300;
process( 200,
boost::bind( &A::foo1, _1, _2, _3, boost::ref( s3 ) ) );
}
Now I know this isn't valid code because in the process() function I somehow need to call foo with instance pointer a. Not sure how to connect the two and not sure why the compiler error is happening.
First of all, you would need to add a reference to your class to the signature of the boost::function:
typedef boost::function<bool (A *, unsigned, unsigned)> FooFunc;
This does require that class A be declared before this typedef. Then, in your process function, you can provide this reference when you call the given FooFunc
bool process( unsigned s1, FooFunc foo )
{
unsigned s2 = 100;
A* a = 0; // pretend this is valid
return foo( a, s1, s2 );
}
Note that I also changed the non-const reference to FooFunc to a value parameter. The rest of your code would then work as it is.
I don't have access to MSVC7 (I really do hope you've got 7.1 and not 7.0). You may need to use the 'Portable Syntax' as described in the boost.function documentation, e.g.:
typedef boost::function<bool , A *, unsigned, unsigned> FooFunc;
There are two pointers to different functions
typedef std::vector<double> TData;
double ( * p_test1 ) ( const TData> &arg);
double ( * p_test2 ) ( const TData> &ar1, char *arg2, char *arg3);
and a method which has as an argument a pointer to the function
double f (double ( * p_test1 ) ( const TData &arg ))
{
//Long and not trivial algorithm processing results of p_test
for ( i = 0;... )
{
double res = p_test (arg); //Some computations
}
}
The f() method contains difficult calculations (here replaced by a for cycle).
Is it possible to templatize this argument (i.e., pointer to a function having different amount of parameters) to get a general function processing both types arguments
double f (double ( * p_test1 ) ( const TData &arg ));
double f (double ( * p_test2 ) ( const TData> &ar1, char *arg2, char *arg3));
Or is there any way how to write such a function, for example to write a pointer to a pointer to the function?
I would like to avoid the partial specialization of f() function because of its complexity (repetitively overwritten of the long code is not efficient).
Thanks for your help...
A method that can take anything can, as a special case, also take function pointer. E.g.
template<typename Function>
double f (Function p_test)
{ ...
// if p_test is a function pointer or has operator(), this will work
double res = p_test (arg);
... }
The problem however gets down to the fact, that the two functions are taking different arguments. So the arguments either have to come somehow bundled to f, there need to be several different implementations anyway, or the arguments will always be the same.
To bundle the arguments, usual method is to use std::bind (C++11) or boost::bind. Say you have a function that needs 3 arguments (test2) and need to pass it to generic algorithm (f) that will only provide the first. And you know the other 2. So you do:
f(bind(&test2, _1, secondarg, thirdarg))
(In C++11 bind is std::bind and _1 is std::placeholders::_1, in Boost bind is boost::bind and _1 is in anonymous namespace provided by the header.) In this case f needs to take any argument, because the return type of bind is unspecified class type with appropriate operator().
You can certainly write a template, at least in C++11:
template <typename ...Args>
double f(double(*fp)(Args...))
{
double res = fp( /* ??? */ );
}
The question is: how do you know how to call the function?
I have a Visual Studio 2008 C++03 project where I would like to use a boost::function object to set the value of a pointer. Something like this:
boost::function< void( int* ) > SetValue;
boost::function< int*() > GetValue;
int* my_value_;
SetValue = boost::bind( my_value_, _1 ); // how should this look?
GetValue = boost::bind( my_value_ ); // and this?
int v;
SetValue( &v );
assert( my_value_ == &v );
int* t = GetValue();
assert( t == my_value_ );
Is there a way to do this or do I need an intermediate function like:
void DoSetValue( int* s, int* v ) { s = v; };
SetValue = boost::bind( DoSetValue, my_value_, _1 );
Thanks
Use Boost.Lambda library:
#include <boost/function.hpp>
#include <boost/lambda/lambda.hpp>
int main()
{
boost::function<void(int*)> SetValue = (boost::lambda::var(my_value) = boost::lambda::_1);
boost::function<int*()> GetValue = boost::lambda::var(my_value);
}
You can find more about using variables in its documentation.
Your first attempt will not work as bind() requires a function (or functor), but you are passing a data pointer, so you need to provide a function that does the work you seek.
Note: if you use C++11, you could use lambdas, to avoid having to create a named function
Note: you need to dereference the pointers in DoSetValue or use references (in which case you need to change the declaration of SetValue as well) -- otherwise the change will not be visible outside the function call
void DoSetValue( int& s, int& v ) { s = v; };
For bind to work that way, you would need a pointer to operator=( int* ). Of course, there is no such thing, so you need an intermediate function.
If you could use lambda or phoenix, there are ways to make a function-object that assigns something to something else. It depends on which library you use, but it would look somewhat like this:
bl::var( my_value_ ) = bl::_1;
I'm doing a linear genetic programming project, where programs are bred and evolved by means of natural evolution mechanisms. Their "DNA" is basically a container (I've used arrays and vectors successfully) which contain function pointers to a set of functions available.
Now, for simple problems, such as mathematical problems, I could use one type-defined function pointer which could point to functions that all return a double and all take as parameters two doubles.
Unfortunately this is not very practical. I need to be able to have a container which can have different sorts of function pointers, say a function pointer to a function which takes no arguments, or a function which takes one argument, or a function which returns something, etc (you get the idea)...
Is there any way to do this using any kind of container ?
Could I do that using a container which contains polymorphic classes, which in their turn have various kinds of function pointers?
I hope someone can direct me towards a solution because redesigning everything I've done so far is going to be painful.
A typical idea for virtual machines is to have a separate stack that is used for argument and return value passing.
Your functions can still all be of type void fn(void), but you do argument passing and returning manually.
You can do something like this:
class ArgumentStack {
public:
void push(double ret_val) { m_stack.push_back(ret_val); }
double pop() {
double arg = m_stack.back();
m_stack.pop_back();
return arg;
}
private:
std::vector<double> m_stack;
};
ArgumentStack stack;
...so a function could look like this:
// Multiplies two doubles on top of the stack.
void multiply() {
// Read arguments.
double a1 = stack.pop();
double a2 = stack.pop();
// Multiply!
double result = a1 * a2;
// Return the result by putting it on the stack.
stack.push(result);
}
This can be used in this way:
// Calculate 4 * 2.
stack.push(4);
stack.push(2);
multiply();
printf("2 * 4 = %f\n", stack.pop());
Do you follow?
You cannot put a polymorphic function in a class, since functions that take (or return) different things cannot be used in the same way (with the same interface), which is something required by polymorphism.
The idea of having a class providing a virtual function for any possible function type you need would work, but (without knowing anything about your problem!) its usage feels weird to me: what functions would a derived class override? Aren't your functions uncorrelated?
If your functions are uncorrelated (if there's no reason why you should group them as members of the same class, or if they would be static function since they don't need member variables) you should opt for something else... If you pick your functions at random you could just have several different containers, one for function type, and just pick a container at random, and then a function within it.
Could you make some examples of what your functions do?
What you mentioned itself can be implemented probably by a container of
std::function or discriminated union like Boost::variant.
For example:
#include <functional>
#include <cstdio>
#include <iostream>
struct F {
virtual ~F() {}
};
template< class Return, class Param = void >
struct Func : F {
std::function< Return( Param ) > f;
Func( std::function< Return( Param ) > const& f ) : f( f ) {}
Return operator()( Param const& x ) const { return f( x ); }
};
template< class Return >
struct Func< Return, void > : F {
std::function< Return() > f;
Func( std::function< Return() > const& f ) : f( f ) {}
Return operator()() const { return f(); }
};
static void f_void_void( void ) { puts("void"); }
static int f_int_int( int x ) { return x; }
int main()
{
F *f[] = {
new Func< void >( f_void_void ),
new Func< int, int >( f_int_int ),
};
for ( F **a = f, **e = f + 2; a != e; ++ a ) {
if ( auto p = dynamic_cast< Func< void >* >( *a ) ) {
(*p)();
}
else if ( auto p = dynamic_cast< Func< int, int >* >( *a ) ) {
std::cout<< (*p)( 1 ) <<'\n';
}
}
}
But I'm not sure this is really what you want...
What do you think about Alf P. Steinbach's comment?
This sort of thing is possible with a bit of work. First it's important to understand why something simpler is not possible: in C/C++, the exact mechanism by which arguments are passed to functions and how return values are obtained from the function depends on the types (and sizes) of the arguments. This is defined in the application binary interface (ABI) which is a set of conventions that allow C++ code compiled by different compilers to interoperate. The language also specifies a bunch of implicit type conversions that occur at the call site. So the short and simple answer is that in C/C++ the compiler cannot emit machine code for a call to a function whose signature is not known at compile time.
Now, you can of course implement something like Javascript or Python in C++, where all values (relevant to these functions) are typed dynamically. You can have a base "Value" class that can be an integer, float, string, tuples, lists, maps, etc. You could use std::variant, but in my opinion this is actually syntactically cumbersome and you're better of doing it yourself:
enum class Type {integer, real, str, tuple, map};
struct Value
{
// Returns the type of this value.
virtual Type type() const = 0;
// Put any generic interfaces you want to have across all Value types here.
};
struct Integer: Value
{
int value;
Type type() const override { return Type::integer; }
};
struct String: Value
{
std::string value;
Type type() const override { return Type::str; }
};
struct Tuple: Value
{
std::vector<Value*> value;
Type type() const override { return Type::tuple; };
}
// etc. for whatever types are interesting to you.
Now you can define a function as anything that takes a single Value* and returns a single Value*. Multiple input or output arguments can be passed in as a Tuple, or a Map:
using Function = Value* (*)(Value*);
All your function implementations will need to get the type and do something appropriate with the argument:
Value* increment(Value* x)
{
switch (x->type())
{
Type::integer:
return new Integer(((Integer*) x)->value + 1);
Type::real:
return new Real(((Real*) x)->value + 1.0);
default:
throw TypeError("expected an integer or real argument.")
}
}
increment is now compatible with the Function type and can be stored in mFuncs. You can now call a function of unknown type on arguments of unknown type and you will get an exception if the arguments don't match, or a result of some unknown type if the arguments are compatible.
Most probably you will want to store the function signature as something you can introspect, i.e. dynamically figure out the number and type of arguments that a Function takes. In this case you can make a base Function class with the necessary introspection functions and provide it an operator () to make it look something like calling a regular function. Then you would derive and implement Function as needed.
This is a sketch, but hopefully contains enough pointers to show the way. There are also more type-safe ways to write this code (I like C-style casts when I've already checked the type, but some people might insist you should use dynamic_cast instead), but I figured that is not the point of this question. You will also have to figure out how Value* objects lifetime is managed and that is an entirely different discussion.