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
How to Make Sure That Std::Random_Shuffle Always Produces a Different Result
Read Func Interp of a Z3 Array from the Z3 Model
Other's Library #Define Naming Conflict
Error: Expression Must Have a Class Type
How to Test Whether Class B Is Derived from Template Family of Classes
Inheriting Constructors and Brace-Or-Equal Initializers
How to Force the Use of Cmov in Gcc and VS
Enum Class Constructor C++ , How to Pass Specific Value
Initializing a Vector of Vectors Having a Fixed Size with Boost Assign
Std::Variant' VS. Inheritance VS. Other Ways (Performance)
Remove Duplicates from a List<Int>
C++: Difference Between Member and Non Member Functions