I am trying to use a lambda to pass in place of a function pointer but VS2010 can't seem to convert it. I have tried using std::function like this and it crashes and I have no idea if I am doing this right!
#include <windows.h>
#include <conio.h>
#include <functional>
#include <iostream>
#include <concrt.h>
void main()
{
std::function<void(void*)> f = [](void*) -> void
{
std::cout << "Hello\n";
};
Concurrency::CurrentScheduler::ScheduleTask(f.target<void(void*)>(), 0);
getch();
}
It seems strange to me that the compiler can't convert such a lambda to a simple function pointer as it captures no variables - also in the case that it did I wonder what can be done.
Is the type of each lambda unique? So I could hack around with a template function using the lambdas' type as a template argument to generate a unique static function that could be called instead and hopefully optimised out?
UPDATED
The below seems to work but is it safe?
#include <windows.h>
#include <conio.h>
#include <iostream>
#include <concrt.h>
template<typename Signature>
struct Bind
{
static Signature method;
static void Call(void* parameter)
{
method(parameter);
}
};
template<typename Signature>
Signature Bind<Signature>::method;
template<typename Signature>
void ScheduleTask(Signature method)
{
Bind<Signature>::method = method;
Concurrency::CurrentScheduler::ScheduleTask(&Bind<Signature>::Call,0);
}
void main()
{
ScheduleTask
(
[](void*)
{
std::cout << "Hello";
}
);
ScheduleTask
(
[](void*)
{
std::cout << " there!\n";
}
);
getch();
}
UPDATED AGAIN
So with the help given I have come up with the shorter:
template<typename Signature>
void (*LambdaBind(Signature))(void*)
{
struct Detail
{
static void Bind(void* parameter)
{
Signature method;
method(parameter);
}
};
return &Detail::Bind;
}
This can be used to wrap a lambda with no closure of void(*)(void*) into the equivalent function pointer. It appears that this will become unnecessary in a later version of VS2010.
So how to get this to work for a lambda with closures?
UPDATED AGAIN!
Works for closures in VS2010 - no idea if it's 'safe' though...
template<typename Signature>
struct Detail2
{
static std::function<void(void*)> method;
static void Bind(void* parameter)
{
method(parameter);
}
};
template<typename Signature>
std::function<void(void*)> Detail2<Signature>::method;
template<typename Signature>
void (*LambdaBind2(Signature method))(void*)
{
Detail2<Signature>::method = method;
return &Detail2<Signature>::Bind;
}
This feature of lambda's was added after VS2010 implemented them, so they don't exist in it yet.
Here's a possible generic work-around, very untested:
#include <functional>
#include <iostream>
namespace detail
{
// helper specializations,
// define forwarding methods
template <typename Lambda, typename Func>
struct lambda_wrapper;
#define DEFINE_OPERATOR \
typedef decltype(&call) function_type; \
operator function_type(void) const \
{ \
return &call; \
}
template <typename Lambda, typename C, typename R>
struct lambda_wrapper<Lambda, R (C::*)(void) const>
{
static R call(void)
{
Lambda x;
return x();
}
DEFINE_OPERATOR
};
template <typename Lambda, typename C, typename R,
typename A0>
struct lambda_wrapper<Lambda, R (C::*)(A0) const>
{
static R call(A0&& p0)
{
Lambda x;
return x(std::forward<A0>(p0));
}
DEFINE_OPERATOR
};
// and so on
#undef DEFINE_OPERATOR
}
// wraps a lambda and provides
// a way to call it statically
template <typename Lambda>
struct lambda_wrapper :
detail::lambda_wrapper<Lambda, decltype(&Lambda::operator())>
{};
template <typename Lambda>
lambda_wrapper<Lambda> wrap_lambda(const Lambda&)
{
return lambda_wrapper<Lambda>();
}
int main(void)
{
auto l = [](){ std::cout << "im broked :(" << std::endl; };
std::function<void(void)> f = wrap_lambda(l);
f();
}
Let me know if any part is confusing.
If scheduling lambdas/function objects in Concurrency::CurrentScheduler is what you want, it may be worth your while looking at ConcRT Sample Pack v0.32 here
The task_scheduler struct can schedule lambdas asynchronously, but be advised, passing by reference may cause bad things to happen (since we are talking about asynchronous scheduling without a join/wait, a reference on the stack may no longer be valid at time of task execution!)
Related
Ok so I already have this as a working example but I'm just trying to clean it up.
currently I have a subscription styled event system with callback routines.
I have no problem with adding regular functions and class member functions into the storage variable for it.
But id like to clean it up by overloading my Event.subscribe method.
Currently it does something like so:
template <class T>
class EventObject
{
public:
void subscribe(const T& arg)
{
this->events.push_back(arg);
}
std::vector<T> events;
}
And then In my main its used like so:
void someCallback(const std::string& line)
{
cout <<line;
}
typedef std::function<void(const std::string& line)> onMessageCallbackFunction;
EventObject<onMessageCallbackFunction> messageCallback;
messageCallback.subscribe(someCallback);
Now the pickle comes forward when I use a Class member function. I hate having to intrinsically bind the function before passing it. It makes the code look dirty.
for instance:
class B
{
void callbk(const std::string& line) {}
};
B b;
using std::placeholders::_1;
onMessageCallbackFunction memfunc = std::bind(&B::callbk, b, _1);
messageCallback.subscribe(memfunc);
Now yea it works, but it looks crappy. what is the syntax so I can just preform:
messageCallback.subscribe(&B::callbk, b);
Tried a few but I cant seem to get it JUST right.
What it is not:
template <class J>
void subscribe(J::T cls,T& t); //Nope.
void subscribe(J&& cls,T& t); //Nope.
SUPER CLOSE: (thx tobi)
template< class J, class... Args >
void subscribe(void(J::*funct)(Args), J& inst) {
using std::placeholders::_1;
subscribe(std::bind(funct, inst, _1));
}
Now just need to generic the argument list.
My suggestion would be to use a lambda (std::bind was obsolete the day it came out because lambdas are superior in almost every way).
It never hurts to spell out the lambda separately. There is no performance cost in doing so. The compiler will elide un-necessary copies.
I would also use std::function to store your signals and convert from the compatible passed-in function type.
Your call-site code then looks something like this, which I think you'll agree is clean and expressive:
EventObject<void(std::string)> messageCallback;
B b;
auto handler = [&b](std::string const& line)
{
b.callbk(line);
};
messageCallback.subscribe(handler);
Complete example:
#include <string>
#include <vector>
#include <functional>
#include <type_traits>
template<class Sig> struct EventObject;
template<class R, class...Args>
struct EventObject<R (Args...)>
{
using slot_type = std::function<R(Args...)>;
template
<
class F,
typename std::enable_if
<
std::is_constructible
<
slot_type,
typename std::decay<F>::type
>::value
>::type * = nullptr
>
void subscribe(F&& f)
{
subscribers_.emplace_back(std::forward<F>(f));
}
std::vector<slot_type> subscribers_;
};
class B
{
public:
void callbk(const std::string& line) {}
};
int main()
{
EventObject<void(std::string)> messageCallback;
B b;
auto handler = [&b](std::string const& line)
{
b.callbk(line);
};
messageCallback.subscribe(handler);
}
what is the syntax so I can just preform:
messageCallback.subscribe(&B::callbk, b);
Your interface already allows to pass any callable, and there is no reason to make it more complicated. The EventObject should not be aware whether the callback is a free function or something else. I completely agree that std::bind is tedious and does not look nice and I would rather use a lambda:
EventObject<onMessageCallbackFunction> messageCallback;
B b;
messageCallback.subscribe([&b](const std::string& line){return b.callbk(line);});
PS: I am not sure if I corretly understand your motivation to use a tempalte. It seems that you want to use it only with onMessageCallbackFunctions, such that simply storing a vector of them should be fine.
PPS: for the sake of completeness here is how you could hide the bind inside the method:
#include <vector>
#include <string>
#include <iostream>
#include <functional>
using std::placeholders::_1;
template <class T>
class EventObject {
public:
void subscribe(const T& arg)
{
this->events.push_back(arg);
}
template<typename C>
void subscribe(void(C::*mem_fun)(const std::string&),C& c){
subscribe(std::bind(mem_fun,c,_1));
}
std::vector<T> events;
};
typedef std::function<void(const std::string& line)> onMessageCallbackFunction;
struct B {
void callbk(const std::string& line) {}
};
int main(){
EventObject<onMessageCallbackFunction> messageCallback;
B b;
messageCallback.subscribe(&B::callbk,b);
}
This is only for member functions that return void and return a string, but I wouldnt even bother to make it generic and just use lambdas.
I'm working on a class that schedules functions by binding them in a queue like this:
std::queue <void()> q;
template<typename R,typename... ArgsT>
void
schedule(R& fn, ArgsT&... args)
{
q.push(std::bind(fn, std::forward<ArgsT>(args)...) );
};
template<typename R,typename... ArgsT>
void
schedule(R&& fn, ArgsT&&... args)
{
q.push(std::bind(fn, std::forward<ArgsT>(args)...) );
};
As you see I made the type in the queue void() to make it hold any type of function objects but now I can't get the return when I execute it. What should I do to solve this?
Note: I don't want to use an external library like boost and I don't know what kind of function the user will pass it.
Note: I don't want to use an external library like boost and I don't
know what's the kind of function the user will pass it.
What I usually do in this case is I use a base class (from Command pattern) in my queue, and then have two implementations, the one wrapping the bind, and the other (also wrapping the bind) exposing a function that allows getting the return value.
Here is an example of the returning specialization (at last):
#include <iostream>
#include <functional>
#include <memory>
struct ACmd
{
virtual void exec() = 0;
virtual ~ACmd(){}
};
template <class F>
struct Cmd;
template <class R, class ... Args>
struct Cmd<R(Args...)> : ACmd
{
R result_;
std::function<R()> func_;
template <class F>
Cmd(F&& func, Args&&... args): result_(), func_()
{
auto f = std::bind(std::forward<F>(func), std::forward<Args>(args)...);
func_ = [f](){
return f();
};
}
virtual void exec(){
result_ = func_();
}
const R& getResult() const {return result_;}
};
// Make function for convenience, could return by value or ptr -
// - your choice
template <class R, class F, class ...Args>
Cmd<R(Args...)>* cmd(F&& func, Args&&... args)
{
return new Cmd<R(Args...)>(func, std::forward<Args>(args)...);
}
//... And overload for void...
int foo(int arg) {
return arg;
}
int main() {
auto x = cmd<int>(foo, 10);
x->exec();
std::cout << x->getResult() << std::endl;
return 0;
}
The result of the execution of each element in the queue, it is void, you have already defined it as such. If the functions passed in are required to return a value, then you would need to limit the type(s) returned to a fixed type, use utilities such as std::any, std::variant or some covariant types (possible with a std::unique_ptr or std::shared_ptr).
The simplest is to fix the return type (at compile time);
template <typename R>
using MQ = std::queue<std::function<R()>>;
MQ<int> q;
See the sample below.
The queue declaration needs to be a queue of objects, such as std::function objects. The return value from a bind can be assigned to a function and then used as expected.
std::function is a polymorphic function wrapper, it implements type erasure patterns akin to any, but is specifically designed for functions and other callable objects.
By way of example;
template <typename R>
using MQ = std::queue<std::function<R()>>;
MQ<int> q;
template<typename R,typename... ArgsT>
void
schedule(R&& fn, ArgsT&&... args)
{
q.push(std::bind(std::forward<R>(fn), std::forward<ArgsT>(args)...) );
};
int main()
{
schedule([](int a) { std::cout << "function called" << std::endl; return a; }, 42);
std::cout << q.front()() << std::endl;
}
I try to understand how https://github.com/tomaka/luawrapper works and
extracted one codepath from it. I simplified it to understand it and
came up with the below code.
What puzzles me is the way struct Binder works and how readIntoFunction() creates the binder function objects in advance of it being used, leading to the creation of a call to the lambda that was supplied at the beginning.
Question now:
I had real problems getting my head around this piece of code. Is it just me that thinks this code is hilarious?
Is there some easier way to achieve the same thing? Is there some easier way to generate a binder function from the type signature of the lambda supplied?
g++ -g -std=c++14 test.cpp -o test.exe
test.cpp:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <functional>
template<typename T> struct tag {};
template<typename TFunctionObject, typename TFirstParamType>
struct Binder {
TFunctionObject function;
TFirstParamType param;
template<typename... TParams>
auto operator()(TParams&&... params) -> decltype(function(param, std::forward<TParams>(params)...)) {
return function(param, std::forward<TParams>(params)...);
}
};
class A {
public:
int a[3];
/* trigger the actual call */
template<typename TCallback>
static int readIntoFunction(TCallback&& callback, A &c, int ) {
return callback();
}
/* at the first call 'callback' is the lambda supplied to
A::ca() at the beginning. Each iteration will generate a
derived call object with one argument less than 'callback' */
template<typename TCallback, typename TFirstType, typename... TTypes>
static int readIntoFunction(TCallback&& callback, A &c, int index, tag<TFirstType>, tag<TTypes>... othersTags)
{
const TFirstType v = c.a[index];
Binder<TCallback, const TFirstType&> binder{ callback, v };
return readIntoFunction(binder, c, index + 1, othersTags...);
}
template<typename TType, typename = void>
struct Split {
template<typename TType2>
static void push(A &c, TType2 value) {
}
};
/* with template packs ready, call readIntoFunction().
the 'value' parameter is the target lambda function to
call */
template<typename TReturnType, typename... TParameters>
struct Split<TReturnType (TParameters...)>
{
template<typename TFunctionObject>
static void push(A &c, TFunctionObject value) noexcept {
A::readIntoFunction(value, c, 0, tag<TParameters>{}...);
}
};
/* split up the function signature into return/parameters,
specialize from (*)() to (). */
template<typename TReturnType, typename... TParameters>
struct Split<TReturnType (*)(TParameters...)>
{
typedef Split<TReturnType(TParameters...)> SubPusher;
template<typename TType>
static void push(A &c, TType value) noexcept {
SubPusher::push(c, value);
}
};
/* entry, called with a lambda function as argument */
template<typename TFunctionType>
auto ca(TFunctionType&& data) {
typedef typename std::decay<TFunctionType>::type RealDataType;
Split<RealDataType>::push(*this, std::forward<TFunctionType>(data));
}
};
int main(int argc, char **argv) {
A c{{ 1, 2, 3}};
c.ca( (int (*)(int,float))[](int a,float b)->int {
std::cout << a << b << std::endl;
});
c.ca( (int (*)(int,float,double))[](int a,float b,double c)->int {
std::cout << a << b << c << std::endl;
});
}
Is there some easier way to generate a binder function from the type signature of the lambda supplied?
The short answer is “No”.
Generally, you could use standard library equivalents, std::function, std::bind, std::placeholders. The implementation code is even more complex. But they're in the standard library, i.e. you don’t have to support that code, and you’ll get documentation.
For this particular case, however, they won’t work. Because the function doesn’t just make a callable thing like std::function, instead it marshals the arguments + return value to LUA.
Other methods exist, but they aren’t necessarily simpler. Sometimes C #defines leads to simpler code. In other cases, external scripts or tools running in a pre-build step generate the boilerplate code from something else (special comments/other markup in your source, or external LUA code, or external protocol/interface definitions).
Generally, to write code like this, reflection support in the programming language helps. Unfortunately, C++ has no reflection. Hence that write-only template code.
I have a C++ problem. I want to generate a type based on the type arguments passed to a templated function of it.
Let me illustrate it.
class A {
template<class B> M() { }
void Z() {
// NOTE: Here I want to call to X on each type that was feed it to M.
X<N1>();
X<N1>();
...
X<NN>();
}
template<class B> X() { }
};
For example
A a;
a.M<int>();
a.M<double>();
then a.Z() executes ...
X<int>();
X<double>();
Another example to take into account unique types
A a;
a.M<int>();
a.M<int>();
a.M<double>();
a.M<double>();
then a.Z() will still executes ...
X<int>();
X<double>();
Note that I am generating the type A based on the calls to M.
OK! I think that for that class A that's conceptually impossible because A is not templated type and then it can not vary in that way, In fact that's not possible for any type in C++ (I think). But I want you to get the idea.
I am looking forward for a way to confront this problem using meta-programming, but any advice or solution or reference is welcome.
No metaprogramming needed.
class A {
using XPtr = void (A::*)();
std::vector<XPtr> x_calls;
std::set<std::type_index> x_types;
template <typename B> void X() { ... }
public:
template <typename B> void M() {
bool is_new = x_types.insert(std::type_index(typeid(B))).second;
if (is_new)
x_calls.push_back(&A::X<B>);
...
}
void Z() {
for (auto&& ptr : x_calls) {
(this->*ptr)();
}
}
};
First off, I think you're interface isn't really MPL. To be MPL you'd call it more like typedef MyType mpl::vector<int, double> and then find a way to build a type that called X<...> for each type. However...
#include <iostream>
#include <typeinfo>
#include <vector>
#include <functional>
#include <algorithm>
using namespace std;
template< typename T>
void X() {
cout<<typeid(T).name()<<endl;
}
struct A {
vector< function<void(void)> > callbacks;
void z() {
for( auto a : callbacks ) a();
}
template<typename T>
void M() {
callbacks.push_back( [](){ X<T>();} );
}
};
int main() {
A a;
a.M<int>();
a.M<double>();
a.z();
return 0;
}
does what you want.
$ g++ --std=c++11 && ./a.out
i
d
Ss
See it live
You can achieve similar functionality using boost::fusion::set and boost::mpl.
class A {
struct functoid {
template<typename T>
void operator(T t)
{
/* do something */
}
}
template<class B> M() {
boost::mpl::for_each<B>(functoid());
}
}
A a;
a.template M<boost::fusion::set<int, double, ...>>();
But, in this case, you need to know the actual types, or, register some callback in operator().
I'm trying to use std::function in conjunction with std::bind, but I'm having some problems.
This works:
#include <functional>
#include <iostream>
void print() {
std::cout << 2;
}
int main() {
std::function<void ()> foo = print;
(*foo.target<void (*)()>())(); //prints 3
}
This crashes at the second line of main:
#include <functional>
#include <iostream>
void print (int i) {
std::cout << i;
}
int main() {
std::function<void ()> foo = std::bind (print, 2);
(*foo.target<void (*)()>())();
}
I'm really holding the std::function<void ()> and need to be able to return the function; not just call it. I expect the usage would be something like this:
#include <functional>
#include <iostream>
void print (int i) {
std::cout << i;
}
int main() {
Container c (std::bind (print, 2));
//I would expect the original
c.func() (3); //prints 3
if (c.func() == print) /* this is what I'm mostly getting at */
}
Is there any way to get the original function to return it, or an alternative? It does kind of conflict with the return type as well, as void (*)() matches the bound signature quite nicely.
This is quite impossible. The whole reason that std::function exists is that function pointers suck horrifically and should never, ever, be used by anyone, ever again, except for the doomed souls bearing the Burning Standards of Hell C interoperation, because they cannot handle functions with state.
A std::function<void()> cannot, in the general case, be converted to a void(*)(). The only reason this works in the first example is because it happens to be a void(*)() originally.
This can be achieved using a little template meta-programming. I recently had use for this while writing a generic C++ wrapper around OpenGL GLUT (which depends on callback function pointers). The approach:
Instantiate an instance of a singleton template type.
Store your std::function as a member of to the singleton instance
Invoke your std::function through a static member function (static member functions and free functions have the same type, so the "invoke" function can be used as a free function pointer)
Tested under C++11 on GCC 4.8.
#include <unistd.h>
#include <thread>
#include <chrono>
#include <mutex>
#include <functional>
#include <iostream>
#include <cmath>
template <const size_t _UniqueId, typename _Res, typename... _ArgTypes>
struct fun_ptr_helper
{
public:
typedef std::function<_Res(_ArgTypes...)> function_type;
static void bind(function_type&& f)
{ instance().fn_.swap(f); }
static void bind(const function_type& f)
{ instance().fn_=f; }
static _Res invoke(_ArgTypes... args)
{ return instance().fn_(args...); }
typedef decltype(&fun_ptr_helper::invoke) pointer_type;
static pointer_type ptr()
{ return &invoke; }
private:
static fun_ptr_helper& instance()
{
static fun_ptr_helper inst_;
return inst_;
}
fun_ptr_helper() {}
function_type fn_;
};
template <const size_t _UniqueId, typename _Res, typename... _ArgTypes>
typename fun_ptr_helper<_UniqueId, _Res, _ArgTypes...>::pointer_type
get_fn_ptr(const std::function<_Res(_ArgTypes...)>& f)
{
fun_ptr_helper<_UniqueId, _Res, _ArgTypes...>::bind(f);
return fun_ptr_helper<_UniqueId, _Res, _ArgTypes...>::ptr();
}
template<typename T>
std::function<typename std::enable_if<std::is_function<T>::value, T>::type>
make_function(T *t)
{
return {t};
}
int main()
{
std::cout << (void*)get_fn_ptr<0>(make_function(::sin))<<std::endl;
return 0;
}
You can't get a function pointer out of an std::function, as there may not even be one. It could be a member function pointer instead, or an object that implements operator().
This isn't possible in general but most C APIs have a 'context' pointer you can pass alongside the C function pointer. So for interop, you can wrap it with something like this (which assumes the API passes this 'context' parameter in first):
template <class R, class... Args>
struct CFunctionPointer
{
std::function<R(Args...)> func;
static R callback(void* context, Args... args)
{
const CFunctionPointer* unpackedThis = reinterpret_cast<const CFunctionPointer*>(context);
return unpackedThis->func(std::forward<Args>(args)...);
}
};
Which would then be called like this:
auto callable = CFunctionPointer<void, const uint8_t*, const uint8_t*>{ [](const uint8_t* begin, const uint8_t* end) { std::cout << "Hello world\n"; } };
cfunc(..., &callable, &callable.callback);
sadly duplicating the argument types twice.