Say I have
class Foo
{
public:
Foo(std::function<void(std::string)> callback1,
std::function<void(int)> callback2) :
callback1(callback1), callback2(callback2)
{
}
private:
std::function<void(std::string)> callback1;
std::function<void(int)> callback2
}
I can easily construct it in the case I'm using plain functions
void callback1Handler(std::string)
{
// i'm a potato
}
void callback2Handler(int)
{
// i'm a teapot
}
int main()
{
Foo foo(callback1Handler, callback2Handler);
return 0;
}
But if I'm using a class, then things get complicated.
I'd like to be able to do something like the Addendum of this answer does
class Main
{
public:
Main()
{
Foo foo(&Main::callback1Handler, &Main::callback2Handler);
}
void callback1Handler(std::string)
{
// i'm a potato
}
void callback2Handler(int)
{
// i'm a teapot
}
}
But that obviously wouldn't compile. To make it work one would need to use either std::bind or lambdas, or something else.
I want to try to avoid the ugliness of std::bind(&Main::callbackNHandler, this, std::placeholders::_1, ..., std::placeholders::_N), which is mostly the ugliness of having those placeholders explicitly specified.
Using lambdas as [=](std::string str){callbackNHandler(str);} is also ugly, because you have to specify every single variable the callback accepts.
It would be great if I could just use &Main::callback1Handler, just like in the Main class example, or &Main::callback1Handler, this, which is a bit more flexible, since you can specify the instance pointer of Main.
Note that Foo constructor has to remain the same and callback1&callback2 member variables have to also remain the same. However, you may overload Foo constructor, making the overload convert method pointers (or whatever else you will make it to accept) into std::functions and store them in callback1&callback2.
template<class T, class R, class...Args>
std::function<R(Args...)> method( T* t, R(T::*m)(Args...) ){
return [=](Args&&...args)->R{
return (t->*m)(std::forward<Args>(args)...);
};
}
then method( instance, &Main::callback1Handler ) should work, up to typos.
It gets simpler in C++14.
The above does needless type erasure: a helper type instead of a lambda lets you avoid that.
template<class T, class Sig>
struct method_t;
template<class T, class R, class... Args>
struct method_t<T,R(Args...)> {
T* t;
R(T::*m)(Args...);
template<class...Ts>
R operator()(Ts&&...ts)const{
return (t->*m)(std::forward<Ts>(ts)...);
}
};
template<class T, class R, class...Args>
method_t<T, R(Args...)> method( T* t, R(T::*m)(Args...) ){
return {t, m};
}
with the same signature. It can even be stored in a std::function<R(Args...)>. The advantage of the above is that there is no needless overhead if the signature of the std::function does not exactly match, or if you don't use a std::function at all.
The downside is 3x as much code.
In C++14 we can simply do:
template<class T, class R, class...Args>
auto method( T* t, R(T::*m)(Args...) ){
return [=](auto&&...args)->R{
return (t->*m)(decltype(args)(args)...);
};
}
which is as brief as the first one, and as powerful as the second one.
Using lambdas as [=](std::string str){callbackNHandler(str);} is also ugly, because you have to specify every single variable the callback accepts.
C++14 generic lambdas solve that problem:
[this](auto... args){ callback1Handler(args...); }
For C++11 you could write a simple utility that can be used like so:
Foo foo(simple_bind(&Main::callback1Handler, this),
simple_bind(&Main::callback2Handler, this));
That would be defined as a function template like this:
template<typename T, typename F>
SimpleBinder<T, F>
simple_bind(F T::* memfn, T* that)
{ return { that, memfn }; }
Where the type SimpleBinder<T, F> is just:
template<typename T, typename F>
struct SimpleBinder
{
T* m_this;
F T::* m_memfn;
template<typename... Args>
void operator()(Args&&... args)
{ (m_this->*m_memfn)(std::forward<Args>(args)...); }
};
This isn't a fully generic utility (for example, it doesn't do anything with the return type of the member function, always returning void, but that is OK for your requirements, where both the std::function objects return void anyway), but it solves the problem of associating an arbitrary member function with a this pointer, and then calling it with some set of arguments.
Although the SimpleBind object appears to accept any arguments, in fact you'll get a nasty compiler error if you try to call it with arguments that aren't compatible with the member function it binds. Again, that's not a problem, because the std::function objects you store it in will ensure that only the right type of arguments are ever passed to it.
Related
Is there a way to determine a return type of a member function pointer?
Code sample:
///// my library
void my_func(auto mptr) { // have to use `auto`
// some logic based on a return type of mptr: int, string, A, etc.
}
///// client code
struct A {
int foo();
std::string bar(int);
};
class B{
public:
A func(int, double);
};
// ... and many other classes
my_func(&A::foo);
my_func(&A::bar);
my_func(&B::func);
// ... many other calls of my_func()
I need to "fill in" my_func().
Edit:
I can't use std::result_of/std::invoke_result as I don't know the full list of parameters of mptr. It's not important with which params a method is supposed to be called as I'm not calling it. I would like to avoid creating an object of base class of mptr even if I'm able to determine it (using declval is ok).
You can use partial template specialization to determine the return type of mptr:
template <typename T>
struct ReturnType;
template <typename Object, typename Return, typename... Args>
struct ReturnType<Return (Object::*)(Args...)>
{
using Type = Return;
};
void my_func(auto mptr) {
typename ReturnType<decltype(mptr)>::Type obj;
}
Live Demo
You can write a function that deduces the type of a member function pointer, and returns the deduced return type. Note that only a declaration, and no definition is needed
template <typename C, typename Ret, typename... Args>
auto ret_type(Ret (C::*)(Args...)) -> Ret;
void my_func(auto mptr)
{
using type = decltype(ret_type(mptr));
}
In my opinion, this is also easier to read than the specialization solution.
Here's a demo
You can also account for cv-qualifiers by adding overloads. e.g.
template <typename C, typename Ret, typename... Args>
auto ret_type(Ret (C::*)(Args...) const) -> Ret;
Here's a demo
Need to create variadic template<T> function with different arg types that will call constructor of T with given arguments, sort of like when creating a thread but reverse (when creating a thread, its constructor calls function at given funct pointer).
So in pseudo code it should look something like this
template<typename T>
T* CreateNew( ARGS ) {
return new T( ARGS ); //Constructor Gets Same Arguments That Were
} //Passed To The Function
Want this to behave like when creating threads, when they call functions with their arguments that are of different types (which I am unsure how to achive).
Its not entirely clear to me but I think you want to look up variadic templates, e.g.:
template <typename T, typename... Args>
T* CreateNew(Args... args) {
return new T(args...);
}
Adding Example:
#include <iostream>
class A {
public:
A(int a){
std::cout<<__PRETTY_FUNCTION__<<std::endl;
}
A(std::string a){
std::cout<<__PRETTY_FUNCTION__<<std::endl;
}
A(int a,std::string b){
std::cout<<__PRETTY_FUNCTION__<<std::endl;
}
};
template<typename T, typename... Args>
T* create(Args... args){
return new T(args...);
}
int main(){
A b(1);
A c("a");
A d(1,"a");
A* bp = create<A>(1);
A* cp = create<A>("a");
A* dp = create<A>(1,"a");
// This code leaks
return 0;
}
Note that because the changes are kept as minimal as possible, we still return a T* here as the original code. Most of the time, this is not a good idea since ownership is passed via raw pointers. Therefore, as suggested by the comments, you might want to use a std::unique_ptr, which would make your CreateNew function basically equivalent to std::make_unique.
The correct way to write this function is
template <typename T, typename... Args>
T* CreateNew(Args&&... args) {
return new T(std::forward<Args>(args)...);
}
Without the forwarding reference Args&& and without std::forward, the original value categories of the passed arguments will not be propagated to T's constructor, causing potential performance and semantic problems.
I'm developing a simple event driven application in C++11 based on the publish/subscribe pattern. Classes have one or more onWhateverEvent() method invoked by the event loop (inversion of control). Since the application is in fact a firmware, where code size is critical and flexibility is not of high priority, the 'subscribe' part is a simple table with event id's and associated handlers.
Here's a very simplified code of the idea:
#include <functional>
enum Events {
EV_TIMER_TICK,
EV_BUTTON_PRESSED
};
struct Button {
void onTick(int event) { /* publish EV_BUTTON_PRESSED */ }
};
struct Menu {
void onButtonPressed(int event) { /* publish EV_SOMETHING_ELSE */ }
};
Button button1;
Button button2;
Menu mainMenu;
std::pair<int, std::function<void(int)>> dispatchTable[] = {
{EV_TIMER_TICK, std::bind(&Button::onTick, &button1, std::placeholders::_1) },
{EV_TIMER_TICK, std::bind(&Button::onTick, &button2, std::placeholders::_1) },
{EV_BUTTON_PRESSED, std::bind(&Menu::onButtonPressed, &mainMenu, std::placeholders::_1) }
};
int main(void)
{
while(1) {
int event = EV_TIMER_TICK; // msgQueue.getEventBlocking();
for (auto& a : dispatchTable) {
if (event == a.first)
a.second(event);
}
}
}
This compiles and runs fine with a desktop compiler, and std:function<void(int)>> fn = std::bind(&SomeClass::onSomething), &someInstance, std::placeholders::_1) elegantly implements type erasure so the event dispatch table can hold handlers of different classes, thus different types.
The problem comes with the embedded compiler (AVR-GCC 4.8.3) which supports C++11, but there's no Standard C++ Library: no <functional> header. I was thinking how can I re-create the above behavior with compiler features only. I evaluated a few options, but there are objections for each (by the compiler or me):
Create an interface with a virtual void Handler::onEvent(int event) method, and derive Button and Menu from it. The dispatch table can hold interface pointers, and virtual method calls do the rest. This is the most simple approach but I don't like the idea of limiting the number of event handler methods to one per class (with doing local if-else event dispatch), and having the overhead of a virtual method call per event.
My second idea still contains a virtual method call, but has no restrictions on the Button and Menu class. It's a virtual method call based type-erasure with functors:
struct FunctBase {
virtual void operator()(int event) = 0;
};
template<typename T>
struct Funct : public FunctBase
{
T* pobj; //instance ptr
void (T::*pmfn)(int); //mem fun ptr
Funct(T* pobj_, void (T::*pmfn_)(int)) : pobj(pobj_), pmfn(pmfn_) {}
void operator()(int ev) override {
(pobj->*pmfn)(ev);
}
};
Funct can hold instance and method pointers, and the dispatch table can be constructed of FunctBase pointers. This way table is as flexible as with function/bind: can hold any class (type) and any number of handlers per class. My only problem that it still contains 1 virtual method call per event, it's just moved to the functor.
My third idea is a simple hack converting method pointers to function pointers:
typedef void (*Pfn)(void*, int);
Pfn pfn1 = reinterpret_cast<Pfn>(&Button::onTick);
Pfn pfn2 = reinterpret_cast<Pfn>(&Menu::onButtonPressed);
As far as I know this is Undefined Behavior and indeed makes the compiler emit a big fat warning. It's based on the assumption that c++ methods have an implicit 1st argument pointing to this. Nonetheless it works, it's lightweight (no virtual calls), and it's flexible.
So my question: Is it possible to do something like option 3 in clean C++ way? I know there's a void* based type-erasure technique (opposed to virtual method call in option 2), but I don't know how to implement it. Looking at desktop version with std::bind also gives me the impression that it binds the first implicit argument to be the instance pointer, but maybe that's just the syntax.
A solid, efficient, std::function<R(Args...)> replacement isn't hard to write.
As we are embedded, we want to avoid allocating memory. So I'd write a small_task< Signature, size_t sz, size_t algn >. It creates a buffer of size sz and alignment algn in which it stores its erased objects.
It also stores a mover, a destroyer, and an invoker function pointer. These pointers can either be locally within the small_task (maximal locality), or within a manual struct vtable { /*...*/ } const* table.
template<class Sig, size_t sz, size_t algn>
struct small_task;
template<class R, class...Args, size_t sz, size_t algn>
struct small_task<R(Args...), sz, algn>{
struct vtable_t {
void(*mover)(void* src, void* dest);
void(*destroyer)(void*);
R(*invoke)(void const* t, Args&&...args);
template<class T>
static vtable_t const* get() {
static const vtable_t table = {
[](void* src, void*dest) {
new(dest) T(std::move(*static_cast<T*>(src)));
},
[](void* t){ static_cast<T*>(t)->~T(); },
[](void const* t, Args&&...args)->R {
return (*static_cast<T const*>(t))(std::forward<Args>(args)...);
}
};
return &table;
}
};
vtable_t const* table = nullptr;
std::aligned_storage_t<sz, algn> data;
template<class F,
class dF=std::decay_t<F>,
// don't use this ctor on own type:
std::enable_if_t<!std::is_same<dF, small_task>{}>* = nullptr,
// use this ctor only if the call is legal:
std::enable_if_t<std::is_convertible<
std::result_of_t<dF const&(Args...)>, R
>{}>* = nullptr
>
small_task( F&& f ):
table( vtable_t::template get<dF>() )
{
// a higher quality small_task would handle null function pointers
// and other "nullable" callables, and construct as a null small_task
static_assert( sizeof(dF) <= sz, "object too large" );
static_assert( alignof(dF) <= algn, "object too aligned" );
new(&data) dF(std::forward<F>(f));
}
// I find this overload to be useful, as it forces some
// functions to resolve their overloads nicely:
// small_task( R(*)(Args...) )
~small_task() {
if (table)
table->destroyer(&data);
}
small_task(small_task&& o):
table(o.table)
{
if (table)
table->mover(&o.data, &data);
}
small_task(){}
small_task& operator=(small_task&& o){
// this is a bit rude and not very exception safe
// you can do better:
this->~small_task();
new(this) small_task( std::move(o) );
return *this;
}
explicit operator bool()const{return table;}
R operator()(Args...args)const{
return table->invoke(&data, std::forward<Args>(args)...);
}
};
template<class Sig>
using task = small_task<Sig, sizeof(void*)*4, alignof(void*) >;
live example.
Another thing missing is a high quality void(Args...) that doesn't care if the passed-in callable has a return value.
The above task supports move, but not copy. Adding copy means that everything stored must be copyable, and requires another function in the vtable (with an implementation similar to move, except src is const and no std::move).
A small amount of C++14 was used, namely the enable_if_t and decay_t aliases and similar. They can be easily written in C++11, or replaced with typename std::enable_if<?>::type.
bind is best replaced with lambdas, honestly. I don't use it even on non-embedded systems.
Another improvement would be to teach it how to deal with small_tasks that are smaller/less aligned by storing their vtable pointer rather than copying it into the data buffer, and wrapping it in another vtable. That would encourage using small_tasks that are just barely large enough for your problem set.
Converting member functions to function pointers is not only undefined behavior, often the calling convention of a function is different than a member function. In particular, this is passed in a particular register under some calling conventions.
Such differences can be subtle, and can crop up when you change unrelated code, or the compiler version changes, or whatever else. So I'd avoid that unless you have little other choice.
As noted, the platform lacks libraries. Every use of std above is tiny, so I'll just write them:
template<class T>struct tag{using type=T;};
template<class Tag>using type_t=typename Tag::type;
using size_t=decltype(sizeof(int));
move
template<class T>
T&& move(T&t){return static_cast<T&&>(t);}
forward
template<class T>
struct remove_reference:tag<T>{};
template<class T>
struct remove_reference<T&>:tag<T>{};
template<class T>using remove_reference_t=type_t<remove_reference<T>>;
template<class T>
T&& forward( remove_reference_t<T>& t ) {
return static_cast<T&&>(t);
}
template<class T>
T&& forward( remove_reference_t<T>&& t ) {
return static_cast<T&&>(t);
}
decay
template<class T>
struct remove_const:tag<T>{};
template<class T>
struct remove_const<T const>:tag<T>{};
template<class T>
struct remove_volatile:tag<T>{};
template<class T>
struct remove_volatile<T volatile>:tag<T>{};
template<class T>
struct remove_cv:remove_const<type_t<remove_volatile<T>>>{};
template<class T>
struct decay3:remove_cv<T>{};
template<class R, class...Args>
struct decay3<R(Args...)>:tag<R(*)(Args...)>{};
template<class T>
struct decay2:decay3<T>{};
template<class T, size_t N>
struct decay2<T[N]>:tag<T*>{};
template<class T>
struct decay:decay2<remove_reference_t<T>>{};
template<class T>
using decay_t=type_t<decay<T>>;
is_convertible
template<class T>
T declval(); // no implementation
template<class T, T t>
struct integral_constant{
static constexpr T value=t;
constexpr integral_constant() {};
constexpr operator T()const{ return value; }
constexpr T operator()()const{ return value; }
};
template<bool b>
using bool_t=integral_constant<bool, b>;
using true_type=bool_t<true>;
using false_type=bool_t<false>;
template<class...>struct voider:tag<void>{};
template<class...Ts>using void_t=type_t<voider<Ts...>>;
namespace details {
template<template<class...>class Z, class, class...Ts>
struct can_apply:false_type{};
template<template<class...>class Z, class...Ts>
struct can_apply<Z, void_t<Z<Ts...>>, Ts...>:true_type{};
}
template<template<class...>class Z, class...Ts>
using can_apply = details::can_apply<Z, void, Ts...>;
namespace details {
template<class From, class To>
using try_convert = decltype( To{declval<From>()} );
}
template<class From, class To>
struct is_convertible : can_apply< details::try_convert, From, To > {};
template<>
struct is_convertible<void,void>:true_type{};
enable_if
template<bool, class=void>
struct enable_if {};
template<class T>
struct enable_if<true, T>:tag<T>{};
template<bool b, class T=void>
using enable_if_t=type_t<enable_if<b,T>>;
result_of
namespace details {
template<class F, class...Args>
using invoke_t = decltype( declval<F>()(declval<Args>()...) );
template<class Sig,class=void>
struct result_of {};
template<class F, class...Args>
struct result_of<F(Args...), void_t< invoke_t<F, Args...> > >:
tag< invoke_t<F, Args...> >
{};
}
template<class Sig>
using result_of = details::result_of<Sig>;
template<class Sig>
using result_of_t=type_t<result_of<Sig>>;
aligned_storage
template<size_t size, size_t align>
struct alignas(align) aligned_storage_t {
char buff[size];
};
is_same
template<class A, class B>
struct is_same:false_type{};
template<class A>
struct is_same<A,A>:true_type{};
live example, about a dozen lines per std library template I needed.
I would put this "std library reimplementation" into namespace notstd to make it clear what is going on.
If you can, use a linker that folds identical functions together, like the gold linker. template metaprogramming can cause binary bloat without a solid linker to strip it.
Your 1st idea is your typical object oriented solution to the problem. It's perfectly fine, but a bit heavy-handed - not quite as usable as std::function. Your 3rd idea is undefined behavior. Nope nope nope.
Your 2nd idea - now there's something we can work with! This is close to how std::function is actually implemented. We can write a class that can take any object that is callable with int and returns void:
class IntFunc {
private:
struct placeholder {
virtual ~placeholder() = default;
virtual void call(int ) = 0;
};
template <typename F>
struct holder : placeholder {
holder(F f) : func(f) { }
void call(int i) override { func(i); }
F func;
};
// if you wrote your own unique_ptr, use it here
// otherwise, will have to add rule of 5 stuff
placeholder* p;
public:
template <typename F>
IntFunc(F f)
: placeholder(new holder<F>(f))
{ }
template <typename Cls>
IntFunc(Cls* instance, void (Cls::*method)(int )) {
auto lambda = [=](int i){ (instance->*method)(i); };
placeholder = new holder<decltype(lambda)>(lambda);
}
void operator()(int i) {
p->call(i);
}
};
With that, you basically have std::function<void(int)> in a usable, generic way.
Now a 4th idea might be to just extend your 3rd idea to something usable. Actually use function pointers:
using Pfn = void (*)(void*, int);
And then use lambdas to make such things:
Pfn buttonOnTick = [](void* ctxt, int i){
static_cast<Button*>(ctxt)->onTick(i);
};
But then you have to hold on to the contexts somehow - which adds extra work.
Before I try to write all the STL stuff by hand, I try to use the STL which I already have from the compiler itself. Because most of the STL code you use is header only, I simply include it and do some minor hacks to get them compiled. In fact id did 10 minutes to get it ready to link!
I used avr-gcc-5.2.0 version without any problems for the task. I have no old installation and I believe it is easier to install the actual version in some minutes instead of fixing problems from the old one.
After compile your example code for avr I got link errors:
build-check-std-a520-nomemdbg-os-dynamic-noncov/main.o: In function `std::__throw_bad_function_call()':
/home/krud/own_components/avr_stl/avr_stl009/testing/main.cpp:42: undefined reference to `operator delete(void*, unsigned int)'
/home/krud/own_components/avr_stl/avr_stl009/testing/main.cpp:42: undefined reference to `operator delete(void*, unsigned int)'
collect2: error: ld returned 1 exit status
Simply write your own __throw_bad_function_call and get rid of the link problem.
For me it makes really no sense to write a own STL implementation. Here I simply used the headers which comes from the compiler installation ( gcc 5.2.0).
How can I create a variadic template function with std::function as a function parameter that accepts a variadic number of arguments? I tried to reduce the problem to a MWE:
#include <functional>
template <class T> void run(std::function<void(T *)> fun, T *obj) { fun(obj); }
template <class T, class... Args>
void run_variadic(std::function<void(T *, Args...)> fun, T *obj, Args... args) {
fun(obj, args...);
}
struct Foo {
void bar() {}
};
int main() {
Foo foo;
std::function<void(Foo *)> fun = &Foo::bar;
run(fun, &foo); // works
run<Foo>(&Foo::bar, &foo); // works
run_variadic(fun, &foo); // works
run_variadic<Foo>(&Foo::bar, &foo); // does not compile
}
It seems like the mere presence of the variadic template parameter in run_variadic makes it impossible to directly call it with a member function pointer. clang's error message is as follows:
main.cpp:21:3: error: no matching function for call to 'run_variadic'
run_variadic<Foo>(&Foo::bar, &foo); // does not compile
^~~~~~~~~~~~~~~~~
main.cpp:6:6: note: candidate template ignored: could not match 'function<void (Foo *, type-parameter-0-1...)>' against 'void (Foo::*)()'
void run_variadic(std::function<void(T *, Args...)> fun, T *obj, Args&&... args) {
^
1 error generated.
Any suggestions on how I can fix run_variadic so that I do not have to go through the extra std::function object?
Background
I have a class hierarchy as
template <class T> class Abstract { ... };
class UnrelatedStuff { ... };
class Derived : public Abstract<UnrelatedStuff> { ... };
There are multiple Derived classes that all have to implement one or more methods to loop over a range of elements. The loop looks something like
#pragma omp parallel for
for (ZFSId i = begin; i != end; ++i) {
callMemFun(i, and, other, args);
}
All loops should be OpenMP-accelerated. I want the accelerator stuff factored out and not repeated in each method of Derived that uses a loop, so that I only have to change one place if e.g. OpenMP would switch to OpenACC.
Thus I am looking for a way to put the loop (and its decoration) in its own function. Moving it to the Abstract base class is not an option either, since the loops are performance-critical and I cannot have an abstract function call in each loop iteration.
You are almost always certainly better off abstracting away the function object:
template <class Functor, class... Args>
void run(Functor&& f, Args&&... args) {
f(std::forward<Args>(args)...);
}
This allows you to do the right thing at call site:
// function object is a lambda that binds to a member function:
run([&](auto... args) { foo.bar(args...); } /*, bar takes no args...*/);
I prefer a lambda to std::function or std::bind but you can also use those if they are already available:
run(std::function<void(Foo *)>{&Foo::bar}, &foo);
run(std::bind(&Foo::bar, &foo));
run(std::mem_fn(&Foo::bar), foo);
I provide a full example program below.
You have now edited the question with new information regarding what you are trying to do.
I'm pretty sure that you don't want to do this, since the OpenMP/OpenACC pragmas like parallel for usually require extra annotations for delivering reasonable performance, and they depend on what you are exactly trying to do at call site.
Still, if you really really want to go this route you can write your own for_each algorithm and dispatch according to an ExecutionAgent (see N3874 and N3731). If OpenMP, TBB, OpenACC parallel task are too slow, you can also easily provide overloads based on e.g. an ExecutionPolicy like this:
template<class RandomAccessRange, class Functor,
class ExecutionPolicy = execution::serial_t>
void for_each(RandomAccessRange&& r, Functor&& f,
ExecutionPolicy&& ex = ExecutionPolicy{}) {
detail::for_each_(std::forward<RandomAccessRange>(r),
std::forward<Functor>(f),
std::forward<ExecutionPolicy>(ex));
}
And then you can implement overloads of for_each_ for each execution policy, e.g.:
namespace detail {
template<class RandomAccessRange, class Functor>
void for_each(RandomAccessRange&& r, Functor&& f, execution::serial_t) {
boost::for_each(std::forward<RandomAccessRange>(r), std::forward<Functor>(f));
}
template<class RandomAccessRange, class Functor>
void for_each(RandomAccessRange&& r, Functor&& f, execution::openmp_t) {
#pragma omp parallel for
for (auto&& v : r) { f(v); }
}
template<class RandomAccessRange, class Functor>
void for_each(RandomAccessRange&& r, Functor&& f, execution::openacc_t) {
#pragma acc parallel for
for (auto&& v : r) { f(v); }
}
template<class RandomAccessRange, class Functor>
void for_each(RandomAccessRange&& r, Functor&& f, execution::tbb_t) {
tbb::parallel_for_each(std::begin(std::forward<RandomAccessRange>(r)),
std::end(std::forward<RandomAccessRange>(r)),
std::forward<Functor>(f));
}
} // namespace detail
Note that the ExecutionPolicy is just a tag, i.e.:
namespace execution {
struct serial_t {}; static const constexpr serial_t serial{};
struct openmp_t {}; static const constexpr openmp_t openmp{};
struct openacc_t {}; static const constexpr openacc_t openacc{};
struct tbb_t {}; static const constexpr tbb_t tbb{};
} // namespace execution
This will at least give you an efficient TBB backend even tho the OpenMP/OpenACC performance will be mediocre at best. You can take a look at the parallel implementation of libstdc++ where they use OpenMP. Their for_each algorithm is over 1000 lines of code and uses work-stealing.
Full example program:
#include <functional>
template <class Functor, class... Args>
void run(Functor&& f, Args&&... args) {
f(std::forward<Args>(args)...);
}
struct Foo { void bar() {} };
int main() {
Foo foo;
run([&](auto... args) { foo.bar(args...); } /*, bar takes no args*/);
run(std::function<void(Foo *)>{ &Foo::bar}, &foo);
run(std::bind(&Foo::bar, &foo));
run(std::mem_fn(&Foo::bar), foo);
}
To answer your comment on the previous answer, that answer can be adapted to support pointers to member functions in the way that you've asked for. The previous answer already works for all callable objects, but not directly with a pointer to member function because those are not callable with the usual f(args) syntax. The following version uses tag dispatch to distinguish between pointers to member functions and traditional callable objects, applying the call syntax appropriate to each case.
template <class Functor, class... Args>
void run_helper(std::false_type, Functor f, Args&&... args)
{
f(std::forward<Args>(args)...);
}
template <class Functor, class Arg0, class... Args>
void run_helper(std::true_type, Functor f, Arg0&& arg0, Args&&... args)
{
(std::forward<Arg0>(arg0).*f)(std::forward<Args>(args)...);
}
template <class Functor, class... Args>
void run(Functor f, Args&&... args)
{
run_helper(typename std::is_member_pointer<Functor>::type(),
f, std::forward<Args>(args)...);
}
This can be used in all the same ways as the previous answer could, but also supports directly passing in a pointer to member function:
run(&Foo::bar, foo);
It even works with overloaded member functions and member functions which are templates, if you explicitly instantiate the run template to bind to a particular overloaded function or function template instantiation.
Live example: http://ideone.com/vsBS4H
I have a pretty exotic problem, since I am trying to create some sort of a compiler...
I want to pass a lambda expression to a templated function like this:
template<class T>
delegate<T>* bind(std::function<T> func)
{
return nullptr;
}
So that I can now call
bind([&](int a) { // do something });
... So normally, this wouldn't be a problem, since std::function is able to capture a lambda. But here the problem is that (let's assume) I don't know or don't want to provide the info about what "T" is exactly. It could be any function signature you could also insert into std::function<>...
I also need to pass this "inferred" signature back to the "delegate" class I want to return and that delegate class needs to be a pointer to class...
For now I have come up with this:
template<class T>
struct delegate : public std::function<T>
{
delegate(const std::function<T>& func) : std::function<T>(func) { }
delegate(const delegate<T>& func) { }
};
template<class T>
delegate<T>* bind(std::function<T>&& func)
{
return new delegate<T>(std::forward<std::function<T>>(func));
}
But the above example of a call to "bind" fails with "failed template argument deduction". How can I get this to work without having to specify the "T" parameter explicitly when calling "bind" (then it works, at least)?
Since in theory my compiler has all the info to workaround this issue, I could just insert the instance of "T", but this would make the generated code unnecessarily convoluted.
BTW, I am using the lastest Clang compiler.
Here is the final solution:
template<typename T> struct get_signature;
template<typename Mem, typename Ret, typename... Args> struct get_signature<Ret(Mem::*)(Args...) const> {
typedef Ret type(Args...);
};
template<class T>
delegate<typename get_signature<decltype(&T::operator())>::type>* bind(T func)
{
return nullptr;
}
Be aware that you may need to adjust the "const" modifiers to your needs.
First, you have completely screwed up your rvalue references. Your forwarding does not work at all.
Secondly, that's impossible in some cases.. For some function objects, you could infer the signature by taking the member function pointer to operator() and inspecting it's signature. But for others, they will be overloaded and it will not work.
template<typename T> struct get_signature;
template<typename Mem, typename Ret, typename... Args>
struct get_signature<Ret(Mem::*)(Args...)> {
typedef Ret(Args...) type;
};
template<class T>
delegate<typename get_signature<&T::operator()>::type>* bind(T func)
{
return nullptr;
}
Thirdly, std::bind?