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.
Related
When compiling the following code:
#include <functional>
template <typename functionSignature>
class Class
{
std::function<functionSignature> func;
public:
Class(const std::function<functionSignature>& arg) : func(arg) {}
void callFunc() { func(); }
};
void f(const int i) {}
int main()
{
Class<void(const int)> a(std::bind(f, 10));
a.callFunc();
return 0;
}
The VS 2015 compiler generates the following error message at the sixth line:
error C2064: term does not evaluate to a function taking 0 arguments.
Now, I believe this is because the compiler thinks functionSignature is not, well, a function signature; the same error happens when I instantiate and try to call operator() on an std::function<int> instead of std::function<int()>, for instance.
How can I guarantee that the template argument will always be a function signature, so that I can call operator() on the std::function?
I suspect you want something like that:
template <typename F>
class Class;
template<typename R, typename... P>
class Class<R(P...)> {
public:
std::function<R(P...)> func;
void callFunc(P... p) { func(p...); }
};
By using partial specialization that way you can easily define the type you want.
As an example, you can use it as:
Class<int(double)> c;
Of course, I noticed that you have no constructors for your class, so to invoke func is not a good idea, but it's quite easy to define it and pass a proper function as an argument.
It follows a complete and working example where I've used the operator() to invoke the function:
#include <functional>
template <typename F>
class Class;
template<typename R, typename... P>
class Class<R(P...)> {
public:
Class(std::function<R(P...)> f): func{f} { }
void operator()(P... p) { func(p...); }
private:
std::function<R(P...)> func;
};
void fn() { }
int main() {
std::function<void()> f = fn;
Class<void()> c{f};
c();
}
Your error is here:
Class<void(const int)> a(std::bind(f, 10));
The function Class::callFunc() invokes func() -- i.e., no arguments. The result of std::bind(f, 10) is also a function that takes no arguments, which is consistent with the template argument to the class template. Using Class<void(const int)> is inconsistent with both the usage in the class template and the initialization.
The solution is easy: Change the errant line to
Class<void()> a(std::bind(f, 10));
Is this what you are trying to do?
http://ideone.com/fork/IZ0Z1A
If functionSignature is NOT a function, std::function will throw errors when you create Class but you could add a constructor and throw there a static_assert(std::is_function<functionSignature>::value == true," ");if you want I guess.
#include <functional>
#include <iostream>
template <typename functionSignature>
class Class
{
public:
std::function<functionSignature> func;
void callFunc() { func(); }
};
void f()
{
std::cout << "hello" << std::endl;
}
int main()
{
Class<decltype(f)> t {f};
t.callFunc();
return 0;
}
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.
The "solution" below compiles but it is not what I want. I would like to pass the put member function to for_each and not *this. Using boost is NOT an option. Can this be solved within C++03?
#include <algorithm>
#include <functional>
#include <vector>
using namespace std;
class Wheel { };
class Car {
public:
void process(const vector<Wheel>& wheel) {
for_each(wheel.begin(), wheel.end(), *this);
}
void operator()(const Wheel& w) { put(w); }
private:
void put(const Wheel& w) { }
};
int main() {
vector<Wheel> w(4);
Car c;
c.process(w);
return 0;
}
Yes it can, using a combination of the mem_fun and bind1st templates:
void process(const vector<Wheel>& wheel) {
for_each(wheel.begin(), wheel.end(), bind1st(mem_fun(&Car::put), this));
}
The call to mem_fun creates a new function object that takes in two arguments - a Car* to act as the receiver and a Wheel, then calls put with the first parameter as the receiver and the second parameter as the argument. Calling bind1st then locks the receiver object as first parameter of this function in place.
However, I think you will need to make one small change to this code to get it to work. The bind1st adapter doesn't play well with functions that take their arguments by const reference, so you might need to change put so that it takes a Wheel by value rather than by reference.
You can use mem_fun_ref: see here.
mem_fun_ref should work in your case where you have vector of objects:
for_each(wheel.begin(), wheel.end(), mem_fun_ref(&Wheel::put));
Note that the above example changes put to be a member of Wheel and not Car. It should give you an idea of how to use it though.
Use mem_fun if you have a vector of pointers to an object
Sure- you can just write your own equivalent of boost::mem_func. TR1 has one too. It's a little repetitive if you want increasing numbers of arguments, but not conceptually hard.
template<typename T, typename mem_func_type> struct mem_func_internal;
template<typename T, typename Ret> struct mem_func_internal<T, Ret (T::*)()> {
typedef Ret(T::* functype)();
T* obj;
functype func;
Ret operator()() {
return obj->*func();
}
};
template<typename T, typename Ret, typename ArgType1> struct mem_func_internal<T, Ret (T::*)(ArgType1) {
typedef Ret(T::* functype)();
T* obj;
functype func;
Ret operator()(ArgType1 arg) {
return obj->*func(arg);
}
}
template<typename T, typename mem_func_type> struct mem_func : public mem_func_internal<T, mem_func_type> {
mem_func(T* object, mem_func_type mem_func)
: obj(object)
, func(mem_func) {}
};
template<typename T, typename mem_func_type> mem_func<T, mem_func_type> bind_mem_func(T* object, mem_func_type func) {
return mem_func<T, mem_func_type>(object, func);
}
// Usage
std::for_each(wheel.begin(), wheel.end(), bind_mem_func(this, &Car::put));
It's been a while since I wrote code like this, so it might be a little off. But that's the gist of it. So hard to write a usage example without just using a lambda.
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!)