Passing boost :: any to boost :: bind results
I am trying to figure out how to write this function:
template <typename Bound>
Bound::result_type callFromAnyList(Bound b, list<any> p)
{
}
Then if I had some function:
double myFunc(string s, int i)
{
return -3.0;
}
I could call it by doing something like this:
list<any> p;
p.push_back((string)"Hello");
p.push_back(7);
double result = callFromAnyList(bind(myFunc, _1, _2), p);
Is it possible to write something like my function callFromAnyList
? Can you check the result type and parameter types from the return type from bind
? And then call any_cast<P1>(*p.begin())
, etc.? I tried to understand the binding code, but it's a little hard to follow and doesn't look like they were writing it with validation in mind.
source to share
As you updated your concerns in the comment sections, here is the answer. Only getting the type of the returned function is possible:
template<typename>
struct return_of;
template<typename R>
struct return_of<R(*)()> {
typedef R type;
};
template<typename R, typename P1>
struct return_of<R(*)(P1)> {
typedef R type;
typedef P1 parameter_1;
};
void foo(int);
template<typename Func>
typename return_of<Func>::parameter_1 bar(Func f) {
return 42;
}
// call: bar(foo);
I think you can see what it boils down to :) You can use the boost function types that already solved this: http://www.boost.org/doc/libs/1_37_0/libs/function_types/doc/html/index. html
source to share
I finished doing this now -
void invoke(void (f)(), list<any>& params)
{
f();
}
template <typename R>
void invoke(R (f)(), list<any>& params)
{
params.push_front(f());
}
template <typename T0>
void invoke(void (f)(T0), list<any>& params)
{
T0 t0 = any_cast<T0>(*params.begin()); params.pop_front();
f(t0);
}
template <typename R, typename T0>
void invoke(R (f)(T0), list<any>& params)
{
T0 t0 = any_cast<T0>(*params.begin()); params.pop_front();
params.push_front(f(t0));
}
template <typename T0, typename T1>
void invoke(void (f)(T0, T1), list<any>& params)
{
T0 t0 = any_cast<T0>(*params.begin()); params.pop_front();
T1 t1 = any_cast<T1>(*params.begin()); params.pop_front();
f(t0, t1);
}
template <typename R, typename T0, typename T1>
void invoke(R (f)(T0, T1), list<any>& params)
{
T0 t0 = any_cast<T0>(*params.begin()); params.pop_front();
T1 t1 = any_cast<T1>(*params.begin()); params.pop_front();
params.push_front(f(t0, t1));
}
template <typename T0, typename T1, typename T2>
void invoke(void (f)(T0, T1, T2), list<any>& params)
{
T0 t0 = any_cast<T0>(*params.begin()); params.pop_front();
T1 t1 = any_cast<T1>(*params.begin()); params.pop_front();
T2 t2 = any_cast<T2>(*params.begin()); params.pop_front();
f(t0, t1, t2);
}
template <typename R, typename T0, typename T1, typename T2>
void invoke(R (f)(T0, T1, T2), list<any>& params)
{
T0 t0 = any_cast<T0>(*params.begin()); params.pop_front();
T1 t1 = any_cast<T1>(*params.begin()); params.pop_front();
T2 t2 = any_cast<T2>(*params.begin()); params.pop_front();
params.push_front(f(t0, t1, t2));
}
I am missing the full power of boost :: bind-like, I cannot handle pointers to pointers, but I also realized that by doing this I have a stack processor. I can keep referring to methods that operator on parameters on the stack.
source to share