A
Andrew Tomazos
I want to write a class that will wrap an arbitrary function and bind
a set of arguments to it so that I can execute it later (perhaps in
another thread, perhaps repeatedly):
void f(const A& a) { ... }
int main()
{
A a = ...;
PFunction pf = MakeFunction(f,a);
...
pf->call(); // executes f(a);
}
I've implemented something using std::function and std::bind, and it
seems to work - but im having trouble getting the arguments to forward
perfectly.
The output of the below test program (which tracks the argument A) is:
constructed at 0x7fff7f008d7f
copied from 0x7fff7f008d7f to 0x7fff7f008a98 <----- HERE
moved from 0x7fff7f008a98 to 0x20ce068
desctructed at 0x7fff7f008a98
desctructed at 0x7fff7f008d7f
used at 0x20ce068
desctructed at 0x20ce068
Is there a way to modify MakeFunction and FunctionT (perhaps using
std::forward or std::decay or something) such that the temporary A is
moved into the Function object, and not copied?
Thanks,
Andrew.
#include <iostream>
#include <memory>
#include <functional>
using namespace std;
class Function;
typedef shared_ptr<Function> PFunction;
class Function
{
public:
virtual void call() = 0;
};
template<class F, class... Args>
class FunctionT : public Function
{
public:
FunctionT(F f, const Args&... args)
: m_f(bind(f,args...))
{}
void call() { m_f(); }
private:
function<void()> m_f;
};
template<class F, class... Args>
shared_ptr<Function> MakeFunction(F&& f, Args&&... args)
{
auto f2 = make_shared<FunctionT<F, Args...>>(f, args...);
return dynamic_pointer_cast<Function> (f2);
}
class A
{
public:
A()
{
cout << "constructed at " << this << endl;
}
A(const A& that)
{
cout << "copied from " << &that << " to " << this << endl;
}
A(A&& that)
{
cout << "moved from " << &that << " to " << this << endl;
}
~A()
{
cout << "desctructed at " << this << endl;
}
};
void f(const A& a)
{
cout << "used at " << &a << endl;
}
PFunction pf;
void f1()
{
pf = MakeFunction(f, A());
}
void f2()
{
pf->call();
}
int main()
{
f1();
f2();
return 0;
}
a set of arguments to it so that I can execute it later (perhaps in
another thread, perhaps repeatedly):
void f(const A& a) { ... }
int main()
{
A a = ...;
PFunction pf = MakeFunction(f,a);
...
pf->call(); // executes f(a);
}
I've implemented something using std::function and std::bind, and it
seems to work - but im having trouble getting the arguments to forward
perfectly.
The output of the below test program (which tracks the argument A) is:
constructed at 0x7fff7f008d7f
copied from 0x7fff7f008d7f to 0x7fff7f008a98 <----- HERE
moved from 0x7fff7f008a98 to 0x20ce068
desctructed at 0x7fff7f008a98
desctructed at 0x7fff7f008d7f
used at 0x20ce068
desctructed at 0x20ce068
Is there a way to modify MakeFunction and FunctionT (perhaps using
std::forward or std::decay or something) such that the temporary A is
moved into the Function object, and not copied?
Thanks,
Andrew.
#include <iostream>
#include <memory>
#include <functional>
using namespace std;
class Function;
typedef shared_ptr<Function> PFunction;
class Function
{
public:
virtual void call() = 0;
};
template<class F, class... Args>
class FunctionT : public Function
{
public:
FunctionT(F f, const Args&... args)
: m_f(bind(f,args...))
{}
void call() { m_f(); }
private:
function<void()> m_f;
};
template<class F, class... Args>
shared_ptr<Function> MakeFunction(F&& f, Args&&... args)
{
auto f2 = make_shared<FunctionT<F, Args...>>(f, args...);
return dynamic_pointer_cast<Function> (f2);
}
class A
{
public:
A()
{
cout << "constructed at " << this << endl;
}
A(const A& that)
{
cout << "copied from " << &that << " to " << this << endl;
}
A(A&& that)
{
cout << "moved from " << &that << " to " << this << endl;
}
~A()
{
cout << "desctructed at " << this << endl;
}
};
void f(const A& a)
{
cout << "used at " << &a << endl;
}
PFunction pf;
void f1()
{
pf = MakeFunction(f, A());
}
void f2()
{
pf->call();
}
int main()
{
f1();
f2();
return 0;
}