Using generic std::function objects with member functions in one class
A non-static member function must be called with an object. That is, it always implicitly passes "this" pointer as its argument.
Because your std::function
signature specifies that your function doesn't take any arguments (<void(void)>
), you must bind the first (and the only) argument.
std::function<void(void)> f = std::bind(&Foo::doSomething, this);
If you want to bind a function with parameters, you need to specify placeholders:
using namespace std::placeholders;
std::function<void(int,int)> f = std::bind(&Foo::doSomethingArgs, this, std::placeholders::_1, std::placeholders::_2);
Or, if your compiler supports C++11 lambdas:
std::function<void(int,int)> f = [=](int a, int b) {
this->doSomethingArgs(a, b);
}
(I don't have a C++11 capable compiler at hand right now, so I can't check this one.)
How to initialize `std::function` with a member-function?
print_add
is a non-static member function of foo
, which means it must be invoked on an instance of Foo
; hence it has an implicit first argument, the this
pointer.
Use a lambda that captures the foo
instance and invokes print_add
on it.
Foo foo;
test([&foo](int i){ foo.print_add(i); });
Another option is to use std::bind
to bind the foo
instance:
test(std::bind(&Foo::print_add, &foo, std::placeholders::_1));
Live demo
std::function to member function
Funcp func =
std::bind(&A::func, &a, std::placeholders::_1, std::placeholders::_2);
Array of generic member functions of base class
I think you’d need something akin std::mem_fn()
but with the added flexibility of converting the object pointer. That should be straight forward to create:
template <typename R, typename X>
class open_mem_fun {
R (X::*fn)();
public:
open_mem_fun(R (X::*fn)()): fn(fn) {}
template <typename T>
R operator()(T* p) const {
return (dynamic_cast<X&>(*p).*fn)();
}
};
template <typename R, typename X>
open_mem_fun<R, X> open_mem_fn(R (X::*fn)()) {
return open_mem_fun<R, X>(fn);
}
The resulting objects should be callable via a suitable std::function
object:
std::function<void(Base*)>(open_mem_fn(&X::XFunc));
C++14: Generic lambda with generic std::function as class member
There is no way you'll be able to choose between two generic lambdas at run-time, as you don't have a concrete signature to type-erase.
If you can make the decision at compile-time, you can templatize the class itself:
template <typename F>
class SomeClass
{
private:
F fooCall;
public:
SomeClass(F&& f) : fooCall{std::move(f)} { }
};
You can then create an helper function to deduce F
:
auto makeSomeClassImpl(std::true_type)
{
auto l = [](auto a){ cout << a.sayHello(); };
return SomeClass<decltype(l)>{std::move(l)};
}
auto makeSomeClassImpl(std::false_type)
{
auto l = [](auto b){ cout << b.sayHello(); };
return SomeClass<decltype(l)>{std::move(l)};
}
template <bool B>
auto makeSomeClass()
{
return makeSomeClassImpl(std::bool_constant<B>{});
}
Question about std::function when using with static member function
For regular functions (and so static method), inherited syntax from C allows both f
and &f
as function pointer.
Both function pointer, and result of std::bind
are callable, and so valid argument to std::function
(and as first argument of std::bind
).
Pass non-static member function to member function of another class
As explained here, pass a lambda that calls the function on the enclosing A
instance:
mB->dopristep([&] (int a, int b) { return g(a, b); }, T, h);
Additionally, you could modify dopristep
to accept a functional which will avoid some overhead:
template <typename F>
int dopristep(F&& f, double t, double h);
Call any object member function on a list of objects using std::function
void CMyService::ApplyToList(void (CMyListItem::*func)(double), double myValue) {
for (auto p : myList) {
(p->*func)(myValue);
}
}
With pre-C++11 compilers:
void CMyService::ApplyToList(void (CMyListItem::*func)(double), double myValue) {
for (std::list<CMyListItem*>::iterator v_Iter = myList.begin();
v_Iter != myList.end(); ++v_Iter) {
((*v_Iter)->*func)(myValue);
}
}
how to create templated-like namespace for member functions
Since you want some input data to stay longer than a single function call, unless it's fully compile-time data a runtime state is inevitable. The question is how you want this data to be encapsulated - different approaches will yield very different (subjective) feelings of how convenient they are.
Based on your usage example:
this->fun1 = foo<a,b>::bar;
If you want to avoid state (or rather encapsulate it) you can create a factory that will create functions for you:
std::function<int(int)> make_func(int a, int b)
{
return [=](int x){ return actual_function(a, b, x); };
}
this->fun1 = make_func(a, b); // now std::function will hold lambda's captured state
This topic is generally known as partial application and I guess boost or other libraries already have a lot of supporting code for such manipulations.
Related Topics
How to Determine Opencv Version
How to Have All the Inputs on the Same Line C++
Reading Every Nth Frame from Videocapture in Opencv
Fastest Way to Check If a File Exists Using Standard C++/C++11,14,17/C
How to Align Text to the Right Using Cout
How Come a Non-Const Reference Cannot Bind to a Temporary Object
Balanced Array Index While Summing an Array from Left and Right
How to Cast Const Uint8_T* to Char*
How to Determine the Boost Version on a System
Why Does Std::Getline() Skip Input After a Formatted Extraction
What Are Copy Elision and Return Value Optimization
C++ Extract Number from the Middle of a String
What Are the Barriers to Understanding Pointers and What Can Be Done to Overcome Them
Difference Between Function Overloading and Template Function Which Is More Appropriate