How to Initialize 'Std::Function' with a Member-Function

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 initialization inside class

std::function<bool(const std::vector<std::string>&)

That function object type can only wrap functions that have the the signature bool(const std::vector<std::string>&). However, none of the functions that try to use have such signature because they are (non-static) member functions. Also, you must use the address-of operator explicitly to get a pointer to a member function and the name must be fully qualified like so: &C::f.

You could bind this to the member functions which would result in a function object of appropriate signature:

std::map<std::string, std::function<bool(const std::vector<std::string>&)> >  funcMap {
{"A", std::bind(&C::f, this, std::placeholders::_1)},
{"B", std::bind(&C::g, this, std::placeholders::_1)},
{"C", std::bind(&C::h, this, std::placeholders::_1)}
^ we bind this pointer to the function object
};

You can use a lambda as well. Bound functions and lambdas are mostly just two ways to write the same thing.


Alternatively you may have intended to in fact store just the member function and not the object pointer in the function object. In that case the type of your function object is wrong as well as the way you call it. This would work:

std::map<std::string, std::function<bool(C*, const std::vector<std::string>&)> >  funcMap {
// ^ note the pointer argument for this
{"A", &C::f},
{"B", &C::g},
{"C", &C::h}
};

// call
c.funcMap["A"](&c, v);
// ^ The object on which the member function is called.
// It doesn't necessarily have to be the same whose funcMap is used.

In this case you don't really need std::function. A map of member function pointers would be sufficient. The syntax of calling a member function pointer is a bit different from using a function object:

std::map<std::string, bool (C::*)(const std::vector<std::string>&) >  funcMap {
{"A", &C::f},
{"B", &C::g},
{"C", &C::h}
};

// call
(c.*c.funcMap["A"])(v);

However, it is unclear why you would need to use member functions at all considering none of them use the state of the object. Another simple solution would be to not use non-static functions in the first place.

Initialize member function arguments as data members in c++

Sentinel values

This can be achieved via a "sentinel" value. If a particular integer is unused (such as -1), try:

void fun(int base = -1) {
if (base == -1) {
base = this->a;
}

// ...
}


std::optional

Another way is to wrap the input up with an std::optional:

void fun(std::optional<int> base = std::nullopt) {
if (!base) {
base = this->a;
}

// Extract actual value by using *.
int base_value = *base;

// Use base_value.
// ...
}

In the example above, base_value is the "default"-corrected int that you desired. A more elegant alternative is to use std::optional<T>::value_or to extract the value:

void fun(std::optional<int> base = std::nullopt) {
int base_value = base.value_or(this->a);

// Use base_value.
// ...
}

How to initialize a reference member variable inside a member function & access it inside other member functions - C++

I think this is the best you can do.

#include <iostream>
using namespace std;

class abc {
public:
int& var;
abc(int& temp) :
var(temp)
{}
void fun2 () {cout << abc::var << endl;}
};

int main() {
int y=9;
abc f(y);
f.fun2();
return 0;
}

A reference is a constant thing — it refers to the same integer for the entire lifespan of the object. That means you need to set it on construction.

How do I assign to member of type std::functionbool(wxString&)

How can you make a variable of some std::function<...> type and assign a value (concrete function) to it later?

std::function has a default constructor that results in an "empty" instance. In your case, just declare the data member std::function<...> m_f and don't explicitly initialize it.

What does it mean to have a variable like described which is uninitialized?

That depends on the type of the variable. In the std::function, it's simply unusable. If you try to inoke an empty std::function, and exception will be thrown.

How can I test whether it is (un)assigned?

std::function has an explicit conversion operator to bool. It evaluates to true when the object is non-empty, i.e.

if (m_f)
m_f(/* parameters... */);
else
; // do nothing, not set yet

How can you make a variable of some std::function<...> type and assign a value (concrete function) to it later?

If you want to later assign lambda expression to the function object through a setter, you can turn this member function into a template, e.g.

template<class Fct>
void setCallback(Fct&& f)
{
m_f = std::forward<Fct>(f);
}

Another option is to pass a std::function with the desired signature to a non-template member function.

Using std::function in member initialization list

You could use lambda expressions. However, if you want to keep the signature as std::function<S32(void)>, you'll need to capture your object.

myClass::myClass() : FnMap1({
{
[this](){ return getData1(); },
[this](){ return getData2(); },
[this](){ return getData3(); },
},
dataRequestor1
})

If you don't want to do this, you could change the signature to pass the this pointer as a parameter to your callbacks. But as Barry points out in the comments, this would not allow you to put callbacks to different classes into the same vector. You could reinterpret_cast the pointer inside the lambda but besides from being ugly and dangerous, how would the caller know what pointer to pass in?

Initialize member functions via constructor

Can the constructor accept function pointers as arguments and assign them to be the implementation of member functions?

No. Not as member functions. But you can certainly have public member function pointers:

class Estimator
{
public:
double (*errorFunc)(std::vector<dtype>, double threshold);
double (*fittingFunc)(std::vector<dtype>, Parameters p);

public:
Estimator(void (*fittingFunc(std::vector<dtype>, Parameters), void (*errorFunc(std::vector<dtype>, double))
: errorFunc(errorFunc)
, fittingFunc(fittingFunc)
{ }

dtype estimate(data);
};

For a nicer (or safer) interface, you can make the function pointers private and have a public member function which simply invokes them.


More generally, if you're okay with the overhead, you can have members of type std::function<double(std::vector<dtype>, double)> and std::function<double(std::vector<dtype>, Parameters)> and then you can use a wider variety of callables (function pointers, but also lambdas, bound member functions, etc.)

Initialization of std::array with function pointer member function of constexpr object

Pointers to free functions are handled differently than pointers to member functions. The TVoidVoid type is a pointer to a free function, but you need a pointer to a Foo member function. Hence, define Foo first,

class Foo { /* As before... */ };

then go with a type alias for the member function (Foo must be known at this point)

// Note the different syntax to the former TVoidVoid
using FooVoidVoid = void (Foo::*)();

Next, Bar must be adjusted such that its data member is of type FooVoidVoid and the constructor accepts this type as an argument (the rest of Bar can be left as it is), and finally defined the array as

std::array<Bar, 3> bar_array = {{Bar{}, Bar{&Foo::myHandler}}};

Note that &Foo::myHandler has nothing to do with any existing Foo instance. It's just a pointer to a Foo member function, and only when you invoke it, this must be brought together with a Foo object (the special operators .* and ->* are meant for this to happen, or use std::invoke once you upgrade to a C++17-enabled compiler).

initialize member function from function pointer

Function pointers are the "C" way of doing things. Here, you can make the RHS a function pointer as suggested in this answer or you can do it the "C++" way by using std::function like:

#include <functional>
class RhsOdeProblem
{
// ...
std::function<double(double,double)> RHS;
//...
};

and intialize in the constructor itself:

constexpr RhsOdeProblem::RhsOdeProblem (std::function<double(double,double)> rhs,
double ti,
double tf,
double dt,
double y0 ) noexcept : startTime{ti}, endTime{tf},
dt{dt} , initValue{y0} ,
analiticalSolution{false},
RHS{rhs}
{ }

or you can do it inside setRhs() :

void RhsOdeProblem::setRhs(std::function<double(double,double)> rhs) {
RHS = rhs;
}

why std::function you may ask, because std::function is a more generic way of doing it (it accepts function pointers, lambdas, classes with overloaded operator() and you can also create std::function from std::bind).

But, std::function might generate a slightly bigger byte-code than function pointers.



Related Topics



Leave a reply



Submit