C++ variable number of arguments - c++

I need to define a virtual function that can take variable number of arguments, problem is c style ellipses does not work for non pod types, I have limited amount of memory (2KB) so i am trying to avoid allocating temp object just to pass to the function, all arguments will be of the same type (a custom shared pointer), I also don't have access to stl or boost. Is there a c++ trick that would allow me to call a func with variable arguments?

Assuming your argument types are of class Arg, you can try this:
class ArgUser {
public:
// syntactic sugar:
void method() { // nullary
doMethod();
}
void method( const Arg & a1 ) { // unary
doMethod( &a1 );
}
void method( const Arg & a1, const Arg & a2 ) { // binary
doMethod( &a1, &a2 );
}
// and so on, until max arity
private:
// actual virtual function:
virtual void doMethod( const Arg * a1=0, const Arg * a2=0 /*etc, until max arity */ ) = 0;
};
This solution has the following properties:
It uses the NVI idiom
It uses pointers because they will not cause temporaries to be created, even for unused default arguments.
It encapsulates the ugly pointer juggling in (inline) wrapper methods.
An alternative solution (that may or may not be more efficient) is this:
class AltArgUser {
public:
// syntactic sugar:
void method() { // nullary
doMethod( 0, 0 );
}
void method( const Arg & a1 ) { // unary
doMethod( &&a1, 1 );
}
void method( const Arg & a1, const Arg & a2 ) { // binary
const Arg * args[] = { &a1, &a2 };
doMethod( args, 2 );
}
// and so on, until max arity
private:
// actual virtual function:
virtual void doMethod( const Arg * args[], size_t numArgs ) = 0;
};
To decide which one to use, you need to study the assembler generated for each method on your particular platform. Whatever you choose, you should definitely keep the wrapper functions.

Define the function to take a pointer to an array of parameters and a parameter for the size of the array.
Also, if you do not want to hard code a fixed sized array you could use alloca to allocate the storage on the stack and not worry about a trip to the heap or calling free.

Pointers to shared pointers are PODs, could you change the prototype to use the memory location of each argument? Like this (not tested):
shared_ptr arg1;
shared_ptr arg2;
ClassWithVirtualFunction c;
c.yourVirtualFunction(&arg1, &arg2, NULL);
ClassWithVirtualFunction
{
virtual void yourVirtualFunction(shared_ptr* first, ...)
{
va_list marker;
va_start( marker, first );
shared_ptr* current=first;
while (current != NULL)
{
/* do stuff with *current */
current = va_arg( marker, shared_ptr* );
}
va_end(marker);
}
}

You can use a fixed array that is actually faster and takes less space than variable number of arguments. Because variable number of arguments does a lot of checks and safety.
mytype arr[3];
arr[0] = a;
// etc
myfunction(arr, 3);

Perhaps if you already have your own custom pointer type, you could define your own basic linked list class (this is C++ after all), with the last "pointer to next" being NULL to indicate the end of the variable number of args.
Something like this:
class MyPointer
{
// Whatever you have/want
};
class MyArgs
{
static int nargs; // Static class variable for total number of args
MyPointer* data;
MyArgs* next;
public:
MyArgs(int nargs)
{
// Some funky constructor to create required number of args...
}
MyPointer* operator[](int at)
{
// Nice overloaded operator for you to get at data
}
};
class PlanToDoStuff
{
public:
virtual void foobar(MyArgs)=0;
};
class ActuallyDoStuff: public PlanToDoStuff
{
public:
void foobar(MyArgs)
{
// Do stuff with args...
}
};
int main()
{
MyArgs args(3);
ActuallyDoStuff dosomething;
dosomething.foobar(args);
}

Related

What does operator() (... mean in C++ [duplicate]

I keep hearing a lot about functors in C++. Can someone give me an overview as to what they are and in what cases they would be useful?
A functor is pretty much just a class which defines the operator(). That lets you create objects which "look like" a function:
// this is a functor
struct add_x {
add_x(int val) : x(val) {} // Constructor
int operator()(int y) const { return x + y; }
private:
int x;
};
// Now you can use it like this:
add_x add42(42); // create an instance of the functor class
int i = add42(8); // and "call" it
assert(i == 50); // and it added 42 to its argument
std::vector<int> in; // assume this contains a bunch of values)
std::vector<int> out(in.size());
// Pass a functor to std::transform, which calls the functor on every element
// in the input sequence, and stores the result to the output sequence
std::transform(in.begin(), in.end(), out.begin(), add_x(1));
assert(out[i] == in[i] + 1); // for all i
There are a couple of nice things about functors. One is that unlike regular functions, they can contain state. The above example creates a function which adds 42 to whatever you give it. But that value 42 is not hardcoded, it was specified as a constructor argument when we created our functor instance. I could create another adder, which added 27, just by calling the constructor with a different value. This makes them nicely customizable.
As the last lines show, you often pass functors as arguments to other functions such as std::transform or the other standard library algorithms. You could do the same with a regular function pointer except, as I said above, functors can be "customized" because they contain state, making them more flexible (If I wanted to use a function pointer, I'd have to write a function which added exactly 1 to its argument. The functor is general, and adds whatever you initialized it with), and they are also potentially more efficient. In the above example, the compiler knows exactly which function std::transform should call. It should call add_x::operator(). That means it can inline that function call. And that makes it just as efficient as if I had manually called the function on each value of the vector.
If I had passed a function pointer instead, the compiler couldn't immediately see which function it points to, so unless it performs some fairly complex global optimizations, it'd have to dereference the pointer at runtime, and then make the call.
Little addition. You can use boost::function, to create functors from functions and methods, like this:
class Foo
{
public:
void operator () (int i) { printf("Foo %d", i); }
};
void Bar(int i) { printf("Bar %d", i); }
Foo foo;
boost::function<void (int)> f(foo);//wrap functor
f(1);//prints "Foo 1"
boost::function<void (int)> b(&Bar);//wrap normal function
b(1);//prints "Bar 1"
and you can use boost::bind to add state to this functor
boost::function<void ()> f1 = boost::bind(foo, 2);
f1();//no more argument, function argument stored in f1
//and this print "Foo 2" (:
//and normal function
boost::function<void ()> b1 = boost::bind(&Bar, 2);
b1();// print "Bar 2"
and most useful, with boost::bind and boost::function you can create functor from class method, actually this is a delegate:
class SomeClass
{
std::string state_;
public:
SomeClass(const char* s) : state_(s) {}
void method( std::string param )
{
std::cout << state_ << param << std::endl;
}
};
SomeClass *inst = new SomeClass("Hi, i am ");
boost::function< void (std::string) > callback;
callback = boost::bind(&SomeClass::method, inst, _1);//create delegate
//_1 is a placeholder it holds plase for parameter
callback("useless");//prints "Hi, i am useless"
You can create list or vector of functors
std::list< boost::function<void (EventArg e)> > events;
//add some events
....
//call them
std::for_each(
events.begin(), events.end(),
boost::bind( boost::apply<void>(), _1, e));
There is one problem with all this stuff, compiler error messages is not human readable :)
A Functor is a object which acts like a function.
Basically, a class which defines operator().
class MyFunctor
{
public:
int operator()(int x) { return x * 2;}
}
MyFunctor doubler;
int x = doubler(5);
The real advantage is that a functor can hold state.
class Matcher
{
int target;
public:
Matcher(int m) : target(m) {}
bool operator()(int x) { return x == target;}
}
Matcher Is5(5);
if (Is5(n)) // same as if (n == 5)
{ ....}
Name "functor" has been traditionaly used in category theory long before C++ appeared on the scene. This has nothing to do with C++ concept of functor. It's better to use name function object instead of what we call "functor" in C++. This is how other programming languages call similar constructs.
Used instead of plain function:
Features:
Function object may have state
Function object fits into OOP (it behaves like every other object).
Cons:
Brings more complexity to the program.
Used instead of function pointer:
Features:
Function object often may be inlined
Cons:
Function object can not be swapped with other function object type during runtime (at least unless it extends some base class, which therefore gives some overhead)
Used instead of virtual function:
Features:
Function object (non-virtual) doesn't require vtable and runtime dispatching, thus it is more efficient in most cases
Cons:
Function object can not be swapped with other function object type during runtime (at least unless it extends some base class, which therefore gives some overhead)
Like others have mentioned, a functor is an object that acts like a function, i.e. it overloads the function call operator.
Functors are commonly used in STL algorithms. They are useful because they can hold state before and between function calls, like a closure in functional languages. For example, you could define a MultiplyBy functor that multiplies its argument by a specified amount:
class MultiplyBy {
private:
int factor;
public:
MultiplyBy(int x) : factor(x) {
}
int operator () (int other) const {
return factor * other;
}
};
Then you could pass a MultiplyBy object to an algorithm like std::transform:
int array[5] = {1, 2, 3, 4, 5};
std::transform(array, array + 5, array, MultiplyBy(3));
// Now, array is {3, 6, 9, 12, 15}
Another advantage of a functor over a pointer to a function is that the call can be inlined in more cases. If you passed a function pointer to transform, unless that call got inlined and the compiler knows that you always pass the same function to it, it can't inline the call through the pointer.
For the newbies like me among us: after a little research I figured out what the code jalf posted did.
A functor is a class or struct object which can be "called" like a function. This is made possible by overloading the () operator. The () operator (not sure what its called) can take any number of arguments. Other operators only take two i.e. the + operator can only take two values (one on each side of the operator) and return whatever value you have overloaded it for. You can fit any number of arguments inside a () operator which is what gives it its flexibility.
To create a functor first you create your class. Then you create a constructor to the class with a parameter of your choice of type and name. This is followed in the same statement by an initializer list (which uses a single colon operator, something I was also new to) which constructs the class member objects with the previously declared parameter to the constructor. Then the () operator is overloaded. Finally you declare the private objects of the class or struct you have created.
My code (I found jalf's variable names confusing)
class myFunctor
{
public:
/* myFunctor is the constructor. parameterVar is the parameter passed to
the constructor. : is the initializer list operator. myObject is the
private member object of the myFunctor class. parameterVar is passed
to the () operator which takes it and adds it to myObject in the
overloaded () operator function. */
myFunctor (int parameterVar) : myObject( parameterVar ) {}
/* the "operator" word is a keyword which indicates this function is an
overloaded operator function. The () following this just tells the
compiler that () is the operator being overloaded. Following that is
the parameter for the overloaded operator. This parameter is actually
the argument "parameterVar" passed by the constructor we just wrote.
The last part of this statement is the overloaded operators body
which adds the parameter passed to the member object. */
int operator() (int myArgument) { return myObject + myArgument; }
private:
int myObject; //Our private member object.
};
If any of this is inaccurate or just plain wrong feel free to correct me!
A functor is a higher-order function that applies a function to the parametrized(ie templated) types. It is a generalization of the map higher-order function. For example, we could define a functor for std::vector like this:
template<class F, class T, class U=decltype(std::declval<F>()(std::declval<T>()))>
std::vector<U> fmap(F f, const std::vector<T>& vec)
{
std::vector<U> result;
std::transform(vec.begin(), vec.end(), std::back_inserter(result), f);
return result;
}
This function takes a std::vector<T> and returns std::vector<U> when given a function F that takes a T and returns a U. A functor doesn't have to be defined over container types, it can be defined for any templated type as well, including std::shared_ptr:
template<class F, class T, class U=decltype(std::declval<F>()(std::declval<T>()))>
std::shared_ptr<U> fmap(F f, const std::shared_ptr<T>& p)
{
if (p == nullptr) return nullptr;
else return std::shared_ptr<U>(new U(f(*p)));
}
Heres a simple example that converts the type to a double:
double to_double(int x)
{
return x;
}
std::shared_ptr<int> i(new int(3));
std::shared_ptr<double> d = fmap(to_double, i);
std::vector<int> is = { 1, 2, 3 };
std::vector<double> ds = fmap(to_double, is);
There are two laws that functors should follow. The first is the identity law, which states that if the functor is given an identity function, it should be the same as applying the identity function to the type, that is fmap(identity, x) should be the same as identity(x):
struct identity_f
{
template<class T>
T operator()(T x) const
{
return x;
}
};
identity_f identity = {};
std::vector<int> is = { 1, 2, 3 };
// These two statements should be equivalent.
// is1 should equal is2
std::vector<int> is1 = fmap(identity, is);
std::vector<int> is2 = identity(is);
The next law is the composition law, which states that if the functor is given a composition of two functions, it should be the same as applying the functor for the first function and then again for the second function. So, fmap(std::bind(f, std::bind(g, _1)), x) should be the same as fmap(f, fmap(g, x)):
double to_double(int x)
{
return x;
}
struct foo
{
double x;
};
foo to_foo(double x)
{
foo r;
r.x = x;
return r;
}
std::vector<int> is = { 1, 2, 3 };
// These two statements should be equivalent.
// is1 should equal is2
std::vector<foo> is1 = fmap(std::bind(to_foo, std::bind(to_double, _1)), is);
std::vector<foo> is2 = fmap(to_foo, fmap(to_double, is));
Here's an actual situation where I was forced to use a Functor to solve my problem:
I have a set of functions (say, 20 of them), and they are all identical, except each calls a different specific function in 3 specific spots.
This is incredible waste, and code duplication. Normally I would just pass in a function pointer, and just call that in the 3 spots. (So the code only needs to appear once, instead of twenty times.)
But then I realized, in each case, the specific function required a completely different parameter profile! Sometimes 2 parameters, sometimes 5 parameters, etc.
Another solution would be to have a base class, where the specific function is an overridden method in a derived class. But do I really want to build all of this INHERITANCE, just so I can pass a function pointer????
SOLUTION: So what I did was, I made a wrapper class (a "Functor") which is able to call any of the functions I needed called. I set it up in advance (with its parameters, etc) and then I pass it in instead of a function pointer. Now the called code can trigger the Functor, without knowing what is happening on the inside. It can even call it multiple times (I needed it to call 3 times.)
That's it -- a practical example where a Functor turned out to be the obvious and easy solution, which allowed me to reduce code duplication from 20 functions to 1.
Like has been repeated, functors are classes that can be treated as functions (overload operator ()).
They are most useful for situations in which you need to associate some data with repeated or delayed calls to a function.
For example, a linked-list of functors could be used to implement a basic low-overhead synchronous coroutine system, a task dispatcher, or interruptable file parsing.
Examples:
/* prints "this is a very simple and poorly used task queue" */
class Functor
{
public:
std::string output;
Functor(const std::string& out): output(out){}
operator()() const
{
std::cout << output << " ";
}
};
int main(int argc, char **argv)
{
std::list<Functor> taskQueue;
taskQueue.push_back(Functor("this"));
taskQueue.push_back(Functor("is a"));
taskQueue.push_back(Functor("very simple"));
taskQueue.push_back(Functor("and poorly used"));
taskQueue.push_back(Functor("task queue"));
for(std::list<Functor>::iterator it = taskQueue.begin();
it != taskQueue.end(); ++it)
{
*it();
}
return 0;
}
/* prints the value stored in "i", then asks you if you want to increment it */
int i;
bool should_increment;
int doSomeWork()
{
std::cout << "i = " << i << std::endl;
std::cout << "increment? (enter the number 1 to increment, 0 otherwise" << std::endl;
std::cin >> should_increment;
return 2;
}
void doSensitiveWork()
{
++i;
should_increment = false;
}
class BaseCoroutine
{
public:
BaseCoroutine(int stat): status(stat), waiting(false){}
void operator()(){ status = perform(); }
int getStatus() const { return status; }
protected:
int status;
bool waiting;
virtual int perform() = 0;
bool await_status(BaseCoroutine& other, int stat, int change)
{
if(!waiting)
{
waiting = true;
}
if(other.getStatus() == stat)
{
status = change;
waiting = false;
}
return !waiting;
}
}
class MyCoroutine1: public BaseCoroutine
{
public:
MyCoroutine1(BaseCoroutine& other): BaseCoroutine(1), partner(other){}
protected:
BaseCoroutine& partner;
virtual int perform()
{
if(getStatus() == 1)
return doSomeWork();
if(getStatus() == 2)
{
if(await_status(partner, 1))
return 1;
else if(i == 100)
return 0;
else
return 2;
}
}
};
class MyCoroutine2: public BaseCoroutine
{
public:
MyCoroutine2(bool& work_signal): BaseCoroutine(1), ready(work_signal) {}
protected:
bool& work_signal;
virtual int perform()
{
if(i == 100)
return 0;
if(work_signal)
{
doSensitiveWork();
return 2;
}
return 1;
}
};
int main()
{
std::list<BaseCoroutine* > coroutineList;
MyCoroutine2 *incrementer = new MyCoroutine2(should_increment);
MyCoroutine1 *printer = new MyCoroutine1(incrementer);
while(coroutineList.size())
{
for(std::list<BaseCoroutine *>::iterator it = coroutineList.begin();
it != coroutineList.end(); ++it)
{
*it();
if(*it.getStatus() == 0)
{
coroutineList.erase(it);
}
}
}
delete printer;
delete incrementer;
return 0;
}
Of course, these examples aren't that useful in themselves. They only show how functors can be useful, the functors themselves are very basic and inflexible and this makes them less useful than, for example, what boost provides.
Functors are used in gtkmm to connect some GUI button to an actual C++ function or method.
If you use the pthread library to make your app multithreaded, Functors can help you.
To start a thread, one of the arguments of the pthread_create(..) is the function pointer to be executed on his own thread.
But there's one inconvenience. This pointer can't be a pointer to a method, unless it's a static method, or unless you specify it's class, like class::method. And another thing, the interface of your method can only be:
void* method(void* something)
So you can't run (in a simple obvious way), methods from your class in a thread without doing something extra.
A very good way of dealing with threads in C++, is creating your own Thread class. If you wanted to run methods from MyClass class, what I did was, transform those methods into Functor derived classes.
Also, the Thread class has this method:
static void* startThread(void* arg)
A pointer to this method will be used as an argument to call pthread_create(..). And what startThread(..) should receive in arg is a void* casted reference to an instance in heap of any Functor derived class, which will be casted back to Functor* when executed, and then called it's run() method.
Except for used in callback, C++ functors can also help to provide a Matlab liking access style to a matrix class. There is a example.
A big advantage of implementing functions as functors is that they can maintain and reuse state between calls. For example, many dynamic programming algorithms, like the Wagner-Fischer algorithm for calculating the Levenshtein distance between strings, work by filling in a large table of results. It's very inefficient to allocate this table every time the function is called, so implementing the function as a functor and making the table a member variable can greatly improve performance.
Below is an example of implementing the Wagner-Fischer algorithm as a functor. Notice how the table is allocated in the constructor, and then reused in operator(), with resizing as necessary.
#include <string>
#include <vector>
#include <algorithm>
template <typename T>
T min3(const T& a, const T& b, const T& c)
{
return std::min(std::min(a, b), c);
}
class levenshtein_distance
{
mutable std::vector<std::vector<unsigned int> > matrix_;
public:
explicit levenshtein_distance(size_t initial_size = 8)
: matrix_(initial_size, std::vector<unsigned int>(initial_size))
{
}
unsigned int operator()(const std::string& s, const std::string& t) const
{
const size_t m = s.size();
const size_t n = t.size();
// The distance between a string and the empty string is the string's length
if (m == 0) {
return n;
}
if (n == 0) {
return m;
}
// Size the matrix as necessary
if (matrix_.size() < m + 1) {
matrix_.resize(m + 1, matrix_[0]);
}
if (matrix_[0].size() < n + 1) {
for (auto& mat : matrix_) {
mat.resize(n + 1);
}
}
// The top row and left column are prefixes that can be reached by
// insertions and deletions alone
unsigned int i, j;
for (i = 1; i <= m; ++i) {
matrix_[i][0] = i;
}
for (j = 1; j <= n; ++j) {
matrix_[0][j] = j;
}
// Fill in the rest of the matrix
for (j = 1; j <= n; ++j) {
for (i = 1; i <= m; ++i) {
unsigned int substitution_cost = s[i - 1] == t[j - 1] ? 0 : 1;
matrix_[i][j] =
min3(matrix_[i - 1][j] + 1, // Deletion
matrix_[i][j - 1] + 1, // Insertion
matrix_[i - 1][j - 1] + substitution_cost); // Substitution
}
}
return matrix_[m][n];
}
};
Functor can also be used to simulate defining a local function within a function. Refer to the question and another.
But a local functor can not access outside auto variables. The lambda (C++11) function is a better solution.
To add on, I have used function objects to fit an existing legacy method to the command pattern; (only place where the beauty of OO paradigm true OCP I felt ); Also adding here the related function adapter pattern.
Suppose your method has the signature:
int CTask::ThreeParameterTask(int par1, int par2, int par3)
We will see how we can fit it for the Command pattern - for this, first, you have to write a member function adapter so that it can be called as a function object.
Note - this is ugly, and may be you can use the Boost bind helpers etc., but if you can't or don't want to, this is one way.
// a template class for converting a member function of the type int function(int,int,int)
//to be called as a function object
template<typename _Ret,typename _Class,typename _arg1,typename _arg2,typename _arg3>
class mem_fun3_t
{
public:
explicit mem_fun3_t(_Ret (_Class::*_Pm)(_arg1,_arg2,_arg3))
:m_Ptr(_Pm) //okay here we store the member function pointer for later use
{}
//this operator call comes from the bind method
_Ret operator()(_Class *_P, _arg1 arg1, _arg2 arg2, _arg3 arg3) const
{
return ((_P->*m_Ptr)(arg1,arg2,arg3));
}
private:
_Ret (_Class::*m_Ptr)(_arg1,_arg2,_arg3);// method pointer signature
};
Also, we need a helper method mem_fun3 for the above class to aid in calling.
template<typename _Ret,typename _Class,typename _arg1,typename _arg2,typename _arg3>
mem_fun3_t<_Ret,_Class,_arg1,_arg2,_arg3> mem_fun3 ( _Ret (_Class::*_Pm) (_arg1,_arg2,_arg3) )
{
return (mem_fun3_t<_Ret,_Class,_arg1,_arg2,_arg3>(_Pm));
}
Now, in order to bind the parameters, we have to write a binder function. So, here it goes:
template<typename _Func,typename _Ptr,typename _arg1,typename _arg2,typename _arg3>
class binder3
{
public:
//This is the constructor that does the binding part
binder3(_Func fn,_Ptr ptr,_arg1 i,_arg2 j,_arg3 k)
:m_ptr(ptr),m_fn(fn),m1(i),m2(j),m3(k){}
//and this is the function object
void operator()() const
{
m_fn(m_ptr,m1,m2,m3);//that calls the operator
}
private:
_Ptr m_ptr;
_Func m_fn;
_arg1 m1; _arg2 m2; _arg3 m3;
};
And, a helper function to use the binder3 class - bind3:
//a helper function to call binder3
template <typename _Func, typename _P1,typename _arg1,typename _arg2,typename _arg3>
binder3<_Func, _P1, _arg1, _arg2, _arg3> bind3(_Func func, _P1 p1,_arg1 i,_arg2 j,_arg3 k)
{
return binder3<_Func, _P1, _arg1, _arg2, _arg3> (func, p1,i,j,k);
}
Now, we have to use this with the Command class; use the following typedef:
typedef binder3<mem_fun3_t<int,T,int,int,int> ,T* ,int,int,int> F3;
//and change the signature of the ctor
//just to illustrate the usage with a method signature taking more than one parameter
explicit Command(T* pObj,F3* p_method,long timeout,const char* key,
long priority = PRIO_NORMAL ):
m_objptr(pObj),m_timeout(timeout),m_key(key),m_value(priority),method1(0),method0(0),
method(0)
{
method3 = p_method;
}
Here is how you call it:
F3 f3 = PluginThreadPool::bind3( PluginThreadPool::mem_fun3(
&CTask::ThreeParameterTask), task1,2122,23 );
Note: f3(); will call the method task1->ThreeParameterTask(21,22,23);.
The full context of this pattern at the following link

What is int operator() [duplicate]

I keep hearing a lot about functors in C++. Can someone give me an overview as to what they are and in what cases they would be useful?
A functor is pretty much just a class which defines the operator(). That lets you create objects which "look like" a function:
// this is a functor
struct add_x {
add_x(int val) : x(val) {} // Constructor
int operator()(int y) const { return x + y; }
private:
int x;
};
// Now you can use it like this:
add_x add42(42); // create an instance of the functor class
int i = add42(8); // and "call" it
assert(i == 50); // and it added 42 to its argument
std::vector<int> in; // assume this contains a bunch of values)
std::vector<int> out(in.size());
// Pass a functor to std::transform, which calls the functor on every element
// in the input sequence, and stores the result to the output sequence
std::transform(in.begin(), in.end(), out.begin(), add_x(1));
assert(out[i] == in[i] + 1); // for all i
There are a couple of nice things about functors. One is that unlike regular functions, they can contain state. The above example creates a function which adds 42 to whatever you give it. But that value 42 is not hardcoded, it was specified as a constructor argument when we created our functor instance. I could create another adder, which added 27, just by calling the constructor with a different value. This makes them nicely customizable.
As the last lines show, you often pass functors as arguments to other functions such as std::transform or the other standard library algorithms. You could do the same with a regular function pointer except, as I said above, functors can be "customized" because they contain state, making them more flexible (If I wanted to use a function pointer, I'd have to write a function which added exactly 1 to its argument. The functor is general, and adds whatever you initialized it with), and they are also potentially more efficient. In the above example, the compiler knows exactly which function std::transform should call. It should call add_x::operator(). That means it can inline that function call. And that makes it just as efficient as if I had manually called the function on each value of the vector.
If I had passed a function pointer instead, the compiler couldn't immediately see which function it points to, so unless it performs some fairly complex global optimizations, it'd have to dereference the pointer at runtime, and then make the call.
Little addition. You can use boost::function, to create functors from functions and methods, like this:
class Foo
{
public:
void operator () (int i) { printf("Foo %d", i); }
};
void Bar(int i) { printf("Bar %d", i); }
Foo foo;
boost::function<void (int)> f(foo);//wrap functor
f(1);//prints "Foo 1"
boost::function<void (int)> b(&Bar);//wrap normal function
b(1);//prints "Bar 1"
and you can use boost::bind to add state to this functor
boost::function<void ()> f1 = boost::bind(foo, 2);
f1();//no more argument, function argument stored in f1
//and this print "Foo 2" (:
//and normal function
boost::function<void ()> b1 = boost::bind(&Bar, 2);
b1();// print "Bar 2"
and most useful, with boost::bind and boost::function you can create functor from class method, actually this is a delegate:
class SomeClass
{
std::string state_;
public:
SomeClass(const char* s) : state_(s) {}
void method( std::string param )
{
std::cout << state_ << param << std::endl;
}
};
SomeClass *inst = new SomeClass("Hi, i am ");
boost::function< void (std::string) > callback;
callback = boost::bind(&SomeClass::method, inst, _1);//create delegate
//_1 is a placeholder it holds plase for parameter
callback("useless");//prints "Hi, i am useless"
You can create list or vector of functors
std::list< boost::function<void (EventArg e)> > events;
//add some events
....
//call them
std::for_each(
events.begin(), events.end(),
boost::bind( boost::apply<void>(), _1, e));
There is one problem with all this stuff, compiler error messages is not human readable :)
A Functor is a object which acts like a function.
Basically, a class which defines operator().
class MyFunctor
{
public:
int operator()(int x) { return x * 2;}
}
MyFunctor doubler;
int x = doubler(5);
The real advantage is that a functor can hold state.
class Matcher
{
int target;
public:
Matcher(int m) : target(m) {}
bool operator()(int x) { return x == target;}
}
Matcher Is5(5);
if (Is5(n)) // same as if (n == 5)
{ ....}
Name "functor" has been traditionaly used in category theory long before C++ appeared on the scene. This has nothing to do with C++ concept of functor. It's better to use name function object instead of what we call "functor" in C++. This is how other programming languages call similar constructs.
Used instead of plain function:
Features:
Function object may have state
Function object fits into OOP (it behaves like every other object).
Cons:
Brings more complexity to the program.
Used instead of function pointer:
Features:
Function object often may be inlined
Cons:
Function object can not be swapped with other function object type during runtime (at least unless it extends some base class, which therefore gives some overhead)
Used instead of virtual function:
Features:
Function object (non-virtual) doesn't require vtable and runtime dispatching, thus it is more efficient in most cases
Cons:
Function object can not be swapped with other function object type during runtime (at least unless it extends some base class, which therefore gives some overhead)
Like others have mentioned, a functor is an object that acts like a function, i.e. it overloads the function call operator.
Functors are commonly used in STL algorithms. They are useful because they can hold state before and between function calls, like a closure in functional languages. For example, you could define a MultiplyBy functor that multiplies its argument by a specified amount:
class MultiplyBy {
private:
int factor;
public:
MultiplyBy(int x) : factor(x) {
}
int operator () (int other) const {
return factor * other;
}
};
Then you could pass a MultiplyBy object to an algorithm like std::transform:
int array[5] = {1, 2, 3, 4, 5};
std::transform(array, array + 5, array, MultiplyBy(3));
// Now, array is {3, 6, 9, 12, 15}
Another advantage of a functor over a pointer to a function is that the call can be inlined in more cases. If you passed a function pointer to transform, unless that call got inlined and the compiler knows that you always pass the same function to it, it can't inline the call through the pointer.
For the newbies like me among us: after a little research I figured out what the code jalf posted did.
A functor is a class or struct object which can be "called" like a function. This is made possible by overloading the () operator. The () operator (not sure what its called) can take any number of arguments. Other operators only take two i.e. the + operator can only take two values (one on each side of the operator) and return whatever value you have overloaded it for. You can fit any number of arguments inside a () operator which is what gives it its flexibility.
To create a functor first you create your class. Then you create a constructor to the class with a parameter of your choice of type and name. This is followed in the same statement by an initializer list (which uses a single colon operator, something I was also new to) which constructs the class member objects with the previously declared parameter to the constructor. Then the () operator is overloaded. Finally you declare the private objects of the class or struct you have created.
My code (I found jalf's variable names confusing)
class myFunctor
{
public:
/* myFunctor is the constructor. parameterVar is the parameter passed to
the constructor. : is the initializer list operator. myObject is the
private member object of the myFunctor class. parameterVar is passed
to the () operator which takes it and adds it to myObject in the
overloaded () operator function. */
myFunctor (int parameterVar) : myObject( parameterVar ) {}
/* the "operator" word is a keyword which indicates this function is an
overloaded operator function. The () following this just tells the
compiler that () is the operator being overloaded. Following that is
the parameter for the overloaded operator. This parameter is actually
the argument "parameterVar" passed by the constructor we just wrote.
The last part of this statement is the overloaded operators body
which adds the parameter passed to the member object. */
int operator() (int myArgument) { return myObject + myArgument; }
private:
int myObject; //Our private member object.
};
If any of this is inaccurate or just plain wrong feel free to correct me!
A functor is a higher-order function that applies a function to the parametrized(ie templated) types. It is a generalization of the map higher-order function. For example, we could define a functor for std::vector like this:
template<class F, class T, class U=decltype(std::declval<F>()(std::declval<T>()))>
std::vector<U> fmap(F f, const std::vector<T>& vec)
{
std::vector<U> result;
std::transform(vec.begin(), vec.end(), std::back_inserter(result), f);
return result;
}
This function takes a std::vector<T> and returns std::vector<U> when given a function F that takes a T and returns a U. A functor doesn't have to be defined over container types, it can be defined for any templated type as well, including std::shared_ptr:
template<class F, class T, class U=decltype(std::declval<F>()(std::declval<T>()))>
std::shared_ptr<U> fmap(F f, const std::shared_ptr<T>& p)
{
if (p == nullptr) return nullptr;
else return std::shared_ptr<U>(new U(f(*p)));
}
Heres a simple example that converts the type to a double:
double to_double(int x)
{
return x;
}
std::shared_ptr<int> i(new int(3));
std::shared_ptr<double> d = fmap(to_double, i);
std::vector<int> is = { 1, 2, 3 };
std::vector<double> ds = fmap(to_double, is);
There are two laws that functors should follow. The first is the identity law, which states that if the functor is given an identity function, it should be the same as applying the identity function to the type, that is fmap(identity, x) should be the same as identity(x):
struct identity_f
{
template<class T>
T operator()(T x) const
{
return x;
}
};
identity_f identity = {};
std::vector<int> is = { 1, 2, 3 };
// These two statements should be equivalent.
// is1 should equal is2
std::vector<int> is1 = fmap(identity, is);
std::vector<int> is2 = identity(is);
The next law is the composition law, which states that if the functor is given a composition of two functions, it should be the same as applying the functor for the first function and then again for the second function. So, fmap(std::bind(f, std::bind(g, _1)), x) should be the same as fmap(f, fmap(g, x)):
double to_double(int x)
{
return x;
}
struct foo
{
double x;
};
foo to_foo(double x)
{
foo r;
r.x = x;
return r;
}
std::vector<int> is = { 1, 2, 3 };
// These two statements should be equivalent.
// is1 should equal is2
std::vector<foo> is1 = fmap(std::bind(to_foo, std::bind(to_double, _1)), is);
std::vector<foo> is2 = fmap(to_foo, fmap(to_double, is));
Here's an actual situation where I was forced to use a Functor to solve my problem:
I have a set of functions (say, 20 of them), and they are all identical, except each calls a different specific function in 3 specific spots.
This is incredible waste, and code duplication. Normally I would just pass in a function pointer, and just call that in the 3 spots. (So the code only needs to appear once, instead of twenty times.)
But then I realized, in each case, the specific function required a completely different parameter profile! Sometimes 2 parameters, sometimes 5 parameters, etc.
Another solution would be to have a base class, where the specific function is an overridden method in a derived class. But do I really want to build all of this INHERITANCE, just so I can pass a function pointer????
SOLUTION: So what I did was, I made a wrapper class (a "Functor") which is able to call any of the functions I needed called. I set it up in advance (with its parameters, etc) and then I pass it in instead of a function pointer. Now the called code can trigger the Functor, without knowing what is happening on the inside. It can even call it multiple times (I needed it to call 3 times.)
That's it -- a practical example where a Functor turned out to be the obvious and easy solution, which allowed me to reduce code duplication from 20 functions to 1.
Like has been repeated, functors are classes that can be treated as functions (overload operator ()).
They are most useful for situations in which you need to associate some data with repeated or delayed calls to a function.
For example, a linked-list of functors could be used to implement a basic low-overhead synchronous coroutine system, a task dispatcher, or interruptable file parsing.
Examples:
/* prints "this is a very simple and poorly used task queue" */
class Functor
{
public:
std::string output;
Functor(const std::string& out): output(out){}
operator()() const
{
std::cout << output << " ";
}
};
int main(int argc, char **argv)
{
std::list<Functor> taskQueue;
taskQueue.push_back(Functor("this"));
taskQueue.push_back(Functor("is a"));
taskQueue.push_back(Functor("very simple"));
taskQueue.push_back(Functor("and poorly used"));
taskQueue.push_back(Functor("task queue"));
for(std::list<Functor>::iterator it = taskQueue.begin();
it != taskQueue.end(); ++it)
{
*it();
}
return 0;
}
/* prints the value stored in "i", then asks you if you want to increment it */
int i;
bool should_increment;
int doSomeWork()
{
std::cout << "i = " << i << std::endl;
std::cout << "increment? (enter the number 1 to increment, 0 otherwise" << std::endl;
std::cin >> should_increment;
return 2;
}
void doSensitiveWork()
{
++i;
should_increment = false;
}
class BaseCoroutine
{
public:
BaseCoroutine(int stat): status(stat), waiting(false){}
void operator()(){ status = perform(); }
int getStatus() const { return status; }
protected:
int status;
bool waiting;
virtual int perform() = 0;
bool await_status(BaseCoroutine& other, int stat, int change)
{
if(!waiting)
{
waiting = true;
}
if(other.getStatus() == stat)
{
status = change;
waiting = false;
}
return !waiting;
}
}
class MyCoroutine1: public BaseCoroutine
{
public:
MyCoroutine1(BaseCoroutine& other): BaseCoroutine(1), partner(other){}
protected:
BaseCoroutine& partner;
virtual int perform()
{
if(getStatus() == 1)
return doSomeWork();
if(getStatus() == 2)
{
if(await_status(partner, 1))
return 1;
else if(i == 100)
return 0;
else
return 2;
}
}
};
class MyCoroutine2: public BaseCoroutine
{
public:
MyCoroutine2(bool& work_signal): BaseCoroutine(1), ready(work_signal) {}
protected:
bool& work_signal;
virtual int perform()
{
if(i == 100)
return 0;
if(work_signal)
{
doSensitiveWork();
return 2;
}
return 1;
}
};
int main()
{
std::list<BaseCoroutine* > coroutineList;
MyCoroutine2 *incrementer = new MyCoroutine2(should_increment);
MyCoroutine1 *printer = new MyCoroutine1(incrementer);
while(coroutineList.size())
{
for(std::list<BaseCoroutine *>::iterator it = coroutineList.begin();
it != coroutineList.end(); ++it)
{
*it();
if(*it.getStatus() == 0)
{
coroutineList.erase(it);
}
}
}
delete printer;
delete incrementer;
return 0;
}
Of course, these examples aren't that useful in themselves. They only show how functors can be useful, the functors themselves are very basic and inflexible and this makes them less useful than, for example, what boost provides.
Functors are used in gtkmm to connect some GUI button to an actual C++ function or method.
If you use the pthread library to make your app multithreaded, Functors can help you.
To start a thread, one of the arguments of the pthread_create(..) is the function pointer to be executed on his own thread.
But there's one inconvenience. This pointer can't be a pointer to a method, unless it's a static method, or unless you specify it's class, like class::method. And another thing, the interface of your method can only be:
void* method(void* something)
So you can't run (in a simple obvious way), methods from your class in a thread without doing something extra.
A very good way of dealing with threads in C++, is creating your own Thread class. If you wanted to run methods from MyClass class, what I did was, transform those methods into Functor derived classes.
Also, the Thread class has this method:
static void* startThread(void* arg)
A pointer to this method will be used as an argument to call pthread_create(..). And what startThread(..) should receive in arg is a void* casted reference to an instance in heap of any Functor derived class, which will be casted back to Functor* when executed, and then called it's run() method.
Except for used in callback, C++ functors can also help to provide a Matlab liking access style to a matrix class. There is a example.
A big advantage of implementing functions as functors is that they can maintain and reuse state between calls. For example, many dynamic programming algorithms, like the Wagner-Fischer algorithm for calculating the Levenshtein distance between strings, work by filling in a large table of results. It's very inefficient to allocate this table every time the function is called, so implementing the function as a functor and making the table a member variable can greatly improve performance.
Below is an example of implementing the Wagner-Fischer algorithm as a functor. Notice how the table is allocated in the constructor, and then reused in operator(), with resizing as necessary.
#include <string>
#include <vector>
#include <algorithm>
template <typename T>
T min3(const T& a, const T& b, const T& c)
{
return std::min(std::min(a, b), c);
}
class levenshtein_distance
{
mutable std::vector<std::vector<unsigned int> > matrix_;
public:
explicit levenshtein_distance(size_t initial_size = 8)
: matrix_(initial_size, std::vector<unsigned int>(initial_size))
{
}
unsigned int operator()(const std::string& s, const std::string& t) const
{
const size_t m = s.size();
const size_t n = t.size();
// The distance between a string and the empty string is the string's length
if (m == 0) {
return n;
}
if (n == 0) {
return m;
}
// Size the matrix as necessary
if (matrix_.size() < m + 1) {
matrix_.resize(m + 1, matrix_[0]);
}
if (matrix_[0].size() < n + 1) {
for (auto& mat : matrix_) {
mat.resize(n + 1);
}
}
// The top row and left column are prefixes that can be reached by
// insertions and deletions alone
unsigned int i, j;
for (i = 1; i <= m; ++i) {
matrix_[i][0] = i;
}
for (j = 1; j <= n; ++j) {
matrix_[0][j] = j;
}
// Fill in the rest of the matrix
for (j = 1; j <= n; ++j) {
for (i = 1; i <= m; ++i) {
unsigned int substitution_cost = s[i - 1] == t[j - 1] ? 0 : 1;
matrix_[i][j] =
min3(matrix_[i - 1][j] + 1, // Deletion
matrix_[i][j - 1] + 1, // Insertion
matrix_[i - 1][j - 1] + substitution_cost); // Substitution
}
}
return matrix_[m][n];
}
};
Functor can also be used to simulate defining a local function within a function. Refer to the question and another.
But a local functor can not access outside auto variables. The lambda (C++11) function is a better solution.
To add on, I have used function objects to fit an existing legacy method to the command pattern; (only place where the beauty of OO paradigm true OCP I felt ); Also adding here the related function adapter pattern.
Suppose your method has the signature:
int CTask::ThreeParameterTask(int par1, int par2, int par3)
We will see how we can fit it for the Command pattern - for this, first, you have to write a member function adapter so that it can be called as a function object.
Note - this is ugly, and may be you can use the Boost bind helpers etc., but if you can't or don't want to, this is one way.
// a template class for converting a member function of the type int function(int,int,int)
//to be called as a function object
template<typename _Ret,typename _Class,typename _arg1,typename _arg2,typename _arg3>
class mem_fun3_t
{
public:
explicit mem_fun3_t(_Ret (_Class::*_Pm)(_arg1,_arg2,_arg3))
:m_Ptr(_Pm) //okay here we store the member function pointer for later use
{}
//this operator call comes from the bind method
_Ret operator()(_Class *_P, _arg1 arg1, _arg2 arg2, _arg3 arg3) const
{
return ((_P->*m_Ptr)(arg1,arg2,arg3));
}
private:
_Ret (_Class::*m_Ptr)(_arg1,_arg2,_arg3);// method pointer signature
};
Also, we need a helper method mem_fun3 for the above class to aid in calling.
template<typename _Ret,typename _Class,typename _arg1,typename _arg2,typename _arg3>
mem_fun3_t<_Ret,_Class,_arg1,_arg2,_arg3> mem_fun3 ( _Ret (_Class::*_Pm) (_arg1,_arg2,_arg3) )
{
return (mem_fun3_t<_Ret,_Class,_arg1,_arg2,_arg3>(_Pm));
}
Now, in order to bind the parameters, we have to write a binder function. So, here it goes:
template<typename _Func,typename _Ptr,typename _arg1,typename _arg2,typename _arg3>
class binder3
{
public:
//This is the constructor that does the binding part
binder3(_Func fn,_Ptr ptr,_arg1 i,_arg2 j,_arg3 k)
:m_ptr(ptr),m_fn(fn),m1(i),m2(j),m3(k){}
//and this is the function object
void operator()() const
{
m_fn(m_ptr,m1,m2,m3);//that calls the operator
}
private:
_Ptr m_ptr;
_Func m_fn;
_arg1 m1; _arg2 m2; _arg3 m3;
};
And, a helper function to use the binder3 class - bind3:
//a helper function to call binder3
template <typename _Func, typename _P1,typename _arg1,typename _arg2,typename _arg3>
binder3<_Func, _P1, _arg1, _arg2, _arg3> bind3(_Func func, _P1 p1,_arg1 i,_arg2 j,_arg3 k)
{
return binder3<_Func, _P1, _arg1, _arg2, _arg3> (func, p1,i,j,k);
}
Now, we have to use this with the Command class; use the following typedef:
typedef binder3<mem_fun3_t<int,T,int,int,int> ,T* ,int,int,int> F3;
//and change the signature of the ctor
//just to illustrate the usage with a method signature taking more than one parameter
explicit Command(T* pObj,F3* p_method,long timeout,const char* key,
long priority = PRIO_NORMAL ):
m_objptr(pObj),m_timeout(timeout),m_key(key),m_value(priority),method1(0),method0(0),
method(0)
{
method3 = p_method;
}
Here is how you call it:
F3 f3 = PluginThreadPool::bind3( PluginThreadPool::mem_fun3(
&CTask::ThreeParameterTask), task1,2122,23 );
Note: f3(); will call the method task1->ThreeParameterTask(21,22,23);.
The full context of this pattern at the following link

Convert from modern C++11 function to raw function pointer

Let's suppose I have the following function interface:
void giveme(void (*p)());
That function simply accepts a pointer to a function with no return type and argument.
I'm wondering if exists a way (without change the interface) to pass a class method as parameter of that function.
I'll try to explain better with an example. I have a class, like:
class Foo {
public:
template<typename T>
void bar();
};
I want to pass bar<T> (of an addressable instance of the class) as parameter of the function giveme.
I thought to bind the method with an object, and obtain the function target.
Something like:
int main(int argc, char *argv[]) {
Foo foo;
std::function<void()> f = std::bind(&Foo::bar<int>, &foo);
giveme(f.target<void()>());
return 0;
}
It compiles, but obviously does not work because, from here:
TargetType shall match the target type, so that typeid(TargetType)==target_type(). Otherwise, the function always returns a null pointer.
So, if exists, what is a way to achieve it?
Here's one (very bad) idea:
Foo * foo_ptr; // maybe thread_local
void foo_call()
{
foo_ptr->bar<int>();
}
int main()
{
Foo foo;
foo_ptr = &foo;
give_me(&foo_call);
}
It's not pretty, but neither is your situation.
There's only one way I know of, and it's a terrible idea, and don't do this.
typedef void (*void_fn)();
struct stateful_void_fn_data = {
void_fn raw;
std::function<void()> actual;
std::atomic_bool in_use;
}
// a global array to hold your function bindings and such
extern stateful_void_fn_data stateful_functions[5];
// N stateless functions that defer to the correct global state
template<int n> void void_fn_impl() {stateful_functions[n].actual();}
extern stateful_void_fn_data stateful_functions[5] =
{{void_fn_impl<0>}, {void_fn_impl<1>}, {void_fn_impl<2>}, {void_fn_impl<3>}, {void_fn_impl<4>}};
// function to register a stateful and get a stateless back
void_fn allocate_void_fn(std::function<void()>&& f) {
for(int i=0; i<5; i++) {
if(stateful_functions[i].in_use.compare_exchange_weak(false, true)) {
stateful_functions[i].actual = std::move(f);
return stateful_functions[i].raw;
}
}
throw std::runtime_error("ran out of stateful functions :(");
}
// function to unregister
void free_void_fn(void_fn f) {
if (f == nullptr) return;
for(int i=0; i<5; i++) {
if (stateful_functions[i].raw == f) {
stateful_functions[i].in_use = false;
return;
}
}
throw std::runtime_error("unknown void function");
}
Basically, I generate 5 void() functions (void_fn_impl<N>), and each calls a function stored in one of the five a global array slots (stateful_functions[i].actual). Then, allocate_void_fn will store any std::function<void()> in the global array, and hand you the void() that calls that entry in the array. This function itself is stateless, because we've stored all the state in the global array. free_void_fn and in_use exist solely to make the functions reusable.
And of course, because RAII is good:
class hidden_state_void_fn {
void_fn raw;
public:
hidden_state_void_fn(std::function<void()>&& f)
:raw(allocate_void_fn(std::move(f)) {}
hidden_state_void_fn(const hidden_state_void_fn&& r) {
raw = r.raw;
r.raw = nullptr;
}
hidden_state_void_fn& operator=(const hidden_state_void_fn&& r) {
free_void_fn(raw);
raw = r.raw;
r.raw = nullptr;
}
~hidden_state_void_fn() {free_void_fn(raw);}
operator void_fn() {return raw;}
operator()() {raw();}
};
std::map<int,std::function<void()>> tasks;
template<int n>
struct task_wrapper{
static void f(){ if (tasks.count(n)) tasks[n](); }
task_wrapper(std::function<void()> fin){ tasks[n]=fin; }
~task_wrapper(){ tasks.erase(n); }
static std::shared_ptr< void(*)() > make(std::function<void()> fin){
auto self=std::make_shared<task_wrapper>(fin);
return { &f, fin };
}
};
A task_wrapper<N>::make(func) return a shared pointer to a stateless function pointer that will call the stateful func.
We can use the the usual techniques to create an array of K function pointers of signature shared_ptr<void(*)()>(*)(). Then we can have a shared_ptr<void(*)()> register_func( std::function<void()> ).
To find blanks, we can either do a linear search, or we could build a table of blanks. This could look like a traditional allocation/free "heap", or a range-tree of blanks, or whatever.
Another approach would be to literally create and save a DLL on the fly then load it and call the symbol. This could be done via hacks (have such a DLL and a known offset to modify, copy and write, then load and run) or by shipping a C++ compiler (or other compiler) with your code (!).

Coding static to instance method trampoline function with templates

I'm trying to recode some rather ugly template coding.
For reference, the original is here: https://codereview.stackexchange.com/questions/69545/recode-c-c-trampoline-function-macros-using-templates
class Final : Base
{
void Foo(){...}
void Bar(){...}
static void init(){
// register_method populates a table of "extern C" function pointers.
register_method( "foo", & FooHandler );
register_method( "bar", & BarHandler );
}
:
// trampolines
static void FooHandler( void* pInstance ) {
Final* f = reinterpret_cast<Final*>(pInstance);
f->Foo();
}
static void BarHandler( void* pInstance ) {
Final* f = reinterpret_cast<Final*>(pInstance);
f->Bar();
}
}
My code interfaces with CPython (C library).
Python runtime sees "myInst.foo" , looks up "foo" in table and invokes:
Final::FooHandler( pointer_to_myInst );
(Note it is possible to typecast a static method to a C function pointer)
FooHandler trampolines to the Foo method of the correct instance of Final.
In reality, the handle is not so clean, and there are many methods each of which requires an identical handler (but with a distinct function address).
I am attempting to abstract the handler mechanism into a base class, something like this:
class Final : Base<Final>
{
void Foo(){...}
void Bar(){...}
static void init(){
// register_method populates a table of "extern C" function pointers.
register_method( "foo", & Foo, Handler< &Foo> );
register_method( "bar", & Bar, Handler< &Bar> );
}
:
}
class Base<Final>
{
typedef void (Final::*FuncSig)(void);
typedef void (Final::*HandlerSig)(void*); // takes 1 pvoid param
void register_method( std::string name, FuncSig meth, HandlerSig handler ) {
...
}
// generic trampoline
template< Sig sig>
static void Handler( void* pInstance ) {
Final* f = reinterpret_cast<Final*>(pInstance);
f ->* sig();
}
}
I'm currently getting stuck in compiler errors (http://ideone.com/vOtbcD), so I'm not even sure whether the technique is valid.
Is there some way to do this, or is this just one of those times where you really need macros?
For reference, the original is here: https://codereview.stackexchange.com/questions/69545/recode-c-c-trampoline-function-macros-using-templates
As can be seen, the original uses rather ugly macros.
register_method needs to be static if you're going to call it from the static init function.
Calling a member function through a member function pointer requires an additional set of parenthesis: (f->*sig)();
With those in place, your test case compiles in C++11 mode. That said, have you considered using std::function and std::bind to do this instead? Hard to tell what that would actually look like without knowing what register_method does, but it might wind up a bit cleaner.
The following code works on ideone (http://ideone.com/vOtbcD):
#include <iostream>
using namespace std;
#include <map>
template<typename T>
class Base
{
public:
typedef void (T::*PFunc)(void);
typedef void (*PHandler)(void*);
using method_map_t = map< string, PHandler >;
static method_map_t& methods( ) {
static method_map_t* map_of_methods{};
if( ! map_of_methods ) map_of_methods = new method_map_t;
return *map_of_methods;
}
static void register_method( string name, PHandler handler ) {
methods()[name] = handler;
}
// generic trampoline
template<PFunc sig>
static void Handler( void* pInstance ) {
T* f = reinterpret_cast<T*>(pInstance);
(f ->* sig)();
}
};
...
class Final : Base<Final>
{
public:
void Foo(){cout<<"got foo";}
void Bar(){cout<<"got bar";}
static void init(){
// register_method populates a table of "extern C" function pointers.
register_method( "foo", static_cast<PHandler>( &Handler<&Final::Foo> ) );
register_method( "bar", static_cast<PHandler>( &Handler<&Final::Bar> ) );
}
};
void InvokeFromC(void* inst, string name) {
Base<Final>::PHandler h = Base<Final>::methods()[name];
(*h)(inst);
}
int main() {
Final* f = new Final{};
f->init();
// simulate invoking from C
InvokeFromC( f, "foo" );
// your code goes here
return 0;
}
Note: (Eelis on IRC) gcc is known not to be able to resolve addresses of function template specializations passed to functions. You can work around it either by declaring separate variables for the function pointers, or using a dirty cast (or a nice cast like boost::implicit_cast)
I have put this code up for review at: https://codereview.stackexchange.com/questions/69876/static-to-instance-method-trampolining-with-templates

Variable number of arguments (va_list) with a function callback?

I am working on implementing a function that would execute another function a few seconds in the future, depending upon the user's input. I have a priority queue of a class (which I am calling TimedEvent) that contains a function pointer to the action I want it to execute at the end of the interval. Say for instance that the user wants the program to call a function "xyz" after 3 seconds, they would create a new TimedEvent with the time and the function pointer to xyz and add it to the priority queue (which is sorted by time, with the soonest events happening first).
I have been able to successfully get the priority queue to pop off the top element after the specified time, but am running into a wall here. The functions I want to call could take a variety of different parameters, from ones that take only a single integer to ones that take 3 integers, a string, etc. and also return different values (some ints, some strings, etc.). I have looked into va_lists (which I have no experience with), but this doesn't seem to be the answer, unless I'm missing something.
In summary (the TL;DR version):
I would like to be able to call these functions as "diverse" as these with the same function pointer:
void func1(int a, int b);<br/>
int func2(int a, string b, OtherClass c);
Am I on the right track with a va_list and a function callback? Can this be implemented easily (or at all)?
Thanks!
I'm inferring here that these functions are API calls that you have no control over. I hacked up something that I think does more or less what you're looking for; it's kind of a rough Command pattern.
#include <iostream>
#include <string>
using namespace std;
//these are the various function types you're calling; optional
typedef int (*ifunc)(const int, const int);
typedef string (*sfunc)(const string&);
// these are the API functions you're calling
int func1(const int a, const int b) { return a + b; }
string func2(const string& a) { return a + " world"; }
// your TimedEvent is given one of these
class FuncBase
{
public:
virtual void operator()() = 0;
};
// define a class like this for each function type
class IFuncWrapper : public FuncBase
{
public:
IFuncWrapper(ifunc fp, const int a, const int b)
: fp_(fp), a_(a), b_(b), result_(0) {}
void operator()() {
result_ = fp_(a_, b_);
}
int getResult() { return result_; }
private:
ifunc fp_;
int a_;
int b_;
int result_;
};
class SFuncWrapper : public FuncBase
{
public:
SFuncWrapper(sfunc fp, const string& a)
: fp_(fp), a_(a), result_("") {}
void operator()() {
result_ = fp_(a_);
}
string getResult() { return result_; }
private:
sfunc fp_;
string a_;
string result_;
};
int main(int argc, char* argv[])
{
IFuncWrapper ifw(func1, 1, 2);
FuncBase* ifp = &ifw;
// pass ifp off to your TimedEvent, which eventually does...
(*ifp)();
// and returns.
int sum = ifw.getResult();
cout << sum << endl;
SFuncWrapper sfw(func2, "hello");
FuncBase* sfp = &sfw;
// pass sfp off to your TimedEvent, which eventually does...
(*sfp)();
// and returns.
string cat = sfw.getResult();
cout << cat << endl;
}
If you have a lot of functions returning the same type, you can define a subclass of FuncBase that implements the appropriate GetResult(), and wrappers for those functions can subclass it. Functions returning void would not require a GetResult() in their wrapper class, of course.
I think boost::bind will be useful to you. For your application, you will probably want to bind all arguments when you create the functor, before putting it on the queue (that is, not use any _1 or _2 placeholders). I don't think you need anything as complicated as lambda expressions/abstractions, but it's good to understand what they are.
+1 ceo for the DIY approach. That will work too, but you have to do all the hard work yourself.
If you want to DIY though, I would suggest using templates instead of defining an xfunc and XFuncWrapper for each combination of types (see code below).
Also, I think allowing different return types is going to be pointless -- whatever code is de-queuing and calling the functions is going to be generic. Either it expects the same type of return from each function, or it expects them to be procedures (return void).
template<typename R>
class FuncWrapper0 : public FuncBase
{
public:
typedef R (*func)();
FuncWrapper0(func fp) : fp_(fp) { }
void operator()() { result_ = fp_(); }
R getResult() { return result_; }
private:
func fp_;
R result_;
};
template<typename R, typename P1>
class FuncWrapper1 : public FuncBase
{
public:
typedef R (*func)(const P1 &);
FuncWrapper1(func fp, const P1 &p1) : fp_(fp), p1_(p1) { }
void operator()() { result_ = fp_(p1_); }
R getResult() { return result_; }
private:
func fp_;
P1 p1_;
R result_;
};
template<typename R, typename P1, typename P2>
class FuncWrapper2 : public FuncBase
{
public:
typedef R (*func)(const P1 &, const P2 &);
FuncWrapper2(func fp, const P1 &p1, const P2 &p2)
: fp_(fp), p1_(p1), p2_(p2) { }
void operator()() { result_ = fp_(p1_, p2_); }
R getResult() { return result_; }
private:
func fp_;
P1 p1_;
P2 p2_;
R result_;
};
What you're trying to do is almost impossible to get to work. You might want to consider packing your parameters into something like an std::vector<boost::any> instead.
Variable parameter lists are really the opposite of what you want. A variable parameter list allows a single function to be called from multiple sites, each with a unique set of parameters. What you want is to call multiple functions from a single site, each with a unique set of parameters -- and a variable parameter list just doesn't support that.
c/invoke is a library that lets you construct arbitrary function calls at runtime, but I think that's overkill in this case. It sounds like you should find a way to "normalize" the callback function's signature so that you can call it the same way every time with a list, structure, union or something that allows you to pass different data through the same interface.
Well, there is a real hardcore trick that exploits the fact that in C every function is a pointer and you can cast a pointer to any other pointer. The original code, where I got this from, was written, when compilers didn't gave errors on implicit casts, so it took me a while to figure out that I had to cast the functions. What it does is that it casts the callback function to a function with a variable number of arguments. But at the same time, the invocation function is cast to a function with 10 arguments, of which not all will be supplied. Especially this last step seems tricky, but you've seen it before, where you give the wrong number of arguments to printf and it just compiles. It might even be that this is what va_start/va_end does under the hood. The code is actually for doing a custom operation on any element in the database, but it could be used for your situation as well:
#include <stdio.h>
typedef int (*INTFUNC)(int,...);
typedef int (*MAPFUNCTION)(int [], INTFUNC, ...);
//------------------CALLBACK FUNCTION----------------
static int callbackfunction(int DatabaseRecord,int myArgument,int *MyResult){
if(DatabaseRecord < myArgument){
printf("mapfunction record:%d<%d -> result %d+%d=%d\n",DatabaseRecord,myArgument,*MyResult,DatabaseRecord,*MyResult+DatabaseRecord);
*MyResult+=DatabaseRecord;}
else{
printf("mapfunction record:%d<%d not true\n",DatabaseRecord,myArgument);
}
return 0; // keep looping
}
//------------------INVOCATION FUNCTION---------------
static int MapDatabase(int DataBase[], INTFUNC func, void* a1, void* a2, void* a3, void* a4, void* a5, void* a6, void* a7, void* a8, void* a9)
{
int cnt,end;
int ret = 0;
end = DataBase[0]+1;
for(cnt = 1;cnt<end;++cnt){
if(func(DataBase[cnt], a1, a2, a3, a4, a5, a6, a7, a8, a9)) {
ret = DataBase[cnt];
break;
}
}
return ret;
}
//------------------TEST----------------
void TestDataBase3(void)
{
int DataBase[20];
int cnt;
int RecordMatch;
int Result = 0;
DataBase[0] = 19;
for(cnt = 1;cnt<20;++cnt){
DataBase[cnt] = cnt;}
// here I do the cast to MAPFUNCTION and INTFUNC
RecordMatch = ((MAPFUNCTION)MapDatabase)(DataBase,(INTFUNC)callbackfunction,11,&Result);
printf("TestDataBase3 Result=%d\n",Result);
}
The same functionality can perfectly be written by using va_start/va_end. It might be the more official way of doing things, but I find it less user friendly. Either the callbackfunction needs to decode its arguments or you need to write a switch/case block inside the invocation function for every combination of arguments that the callback function can have. This means that you have to supply the format of the arguments (just like printf does) or you have to require that all arguments are the same and you just supply the number of arguments, but then you still have to write a case for each amount of arguments. Here is an example where the callback function decodes the arguments:
#include <stdio.h>
#include <stdarg.h>
//------------------CALLBACK FUNCTION----------------
static int callbackfunction(int DatabaseRecord,va_list vargs)
{
int myArgument = va_arg(vargs, int); // The callbackfunction is responsible for knowing the argument types
int *MyResult = va_arg(vargs, int*);
if(DatabaseRecord < myArgument){
printf("mapfunction record:%d<%d -> result %d+%d=%d\n",DatabaseRecord,myArgument,*MyResult,DatabaseRecord,*MyResult+DatabaseRecord);
*MyResult+=DatabaseRecord;}
else{
printf("mapfunction record:%d<%d not true\n",DatabaseRecord,myArgument);
}
return 0; // keep looping
}
//------------------INVOCATION FUNCTION---------------
static int MapDatabase(int DataBase[], int (*func)(int,va_list), int numargs, ...)
{
int cnt,end;
int ret = 0;
va_list vargs;
end = DataBase[0]+1;
for(cnt = 1;cnt<end;++cnt){
va_start( vargs, numargs ); // needs to be called from within the loop, because va_arg can't be reset
if(func(DataBase[cnt], vargs)) {
ret = DataBase[cnt];
break;
}
va_end( vargs ); // avoid memory leaks, call va_end
}
return ret;
}
//------------------TEST----------------
void TestDataBase4(void)
{
int DataBase[20];
int cnt;
int RecordMatch;
int Result = 0;
DataBase[0] = 19;
for(cnt = 1;cnt<20;++cnt){
DataBase[cnt] = cnt;}
RecordMatch = MapDatabase(DataBase,callbackfunction,2,11,&Result);
printf("TestDataBase4a Result=%d\n",Result);
Result = 0;
RecordMatch = MapDatabase(DataBase,callbackfunction,0,11,&Result); // As a hack: It even works if you don't supply the number of arguments.
printf("TestDataBase4b Result=%d\n",Result);
}
#Redef, if your compiler optimizes args into registers, it need not push them on the stack unless they are vargs. This means, in your first example, that callbackfunction will be expecting args in registers whilst the caller using INTFUNC (with a vargs decl) pushes them on the stack.
The result will be that the callback doesn't see the args.