#include <functional>
struct A
{
int func(int x, int y)
{
return x+y;
}
};
int main()
{
typedef std::function<int(int, int) > Funcp;
A a;
//Funcp func = std:::bind(&A::func, &a);
Funcp func = std::bind(&A::func, a, std::placeholders::_1);
return 0;
}
I am getting errors in both of the above bind functions:
error C2825: '_Fty': must be a class or namespace when followed by '::'
Where is the syntax error? I am using visual studio 2010
Funcp func =
std::bind(&A::func, &a, std::placeholders::_1, std::placeholders::_2);
It took a while for me to figure out what's happening. So adding it here for the benefit of others, where an explanation would help. I've renamed some functions and variables for more clarity.
#include <functional>
struct A
{
int MemberFunc(int x, int y)
{
return x+y;
}
};
int main()
{
typedef std::function<int(int, int)> OrdinaryFunc;
A a;
OrdinaryFunc ofunc = std::bind(&A::MemberFunc, a, std::placeholders::_1, std::placeholders::_2);
int z = ofunc(10, 20); // Invoke like an ordinary function
return 0;
}
Class member functions have an implicit/hidden parameter which points to the object (this pointer). These member functions can be invoked only by providing an object, which makes it different from an ordinary function.
std::bind can be used to "convert" a member function into an ordinary function by passing the object (pointer or reference). It has be the first argument in the list of args (&a or a in this case) following the member function. In the new function, the object is bound to the implicit/hidden parameter of the member function, and need not be passed when invoked. The unbound arguments are represented by the placeholders _1, _2 and have to be passed when invoked.
Related
I've got some problem using std::function
It works with static int funcAB but, in reality, I need std function for non-static in class.
#include <functional>
#include <iostream>
class test{
public:
std::function<int (int, int)> func;
int funcAB(int a, int b){
return a + b;
}
test(){
func = test::funcAB;
}
};
int main(){
using namespace std;
test A;
cout <<A.funcAB(10,11) << endl;
cout <<A.func(11,12) << endl;
}
Error:
main.cpp:11:22: error: invalid use of non-static member function ‘int test::funcAB(int, int)’
func = test::funcAB;
^~~~~~
There are two problems here:
The first is that to get a pointer to a member function you need to use the address-of operator &. As in &test::funcAB.
The other problem is that non-static member functions needs an object to be called on. If you don't have an object, you can't call it.
To solve the second problem either use std::bind
using namespace std::placeholders; // for _1, _2, _3...
func = std::bind(&test::funcAB, this, _1, _2);
Or use a lambda
func = [this](int a, int b)
{
return funcAB(a, b);
};
Lambdas are generally recommended over std::bind.
Pointer to non-static member functions are different, you have to invoke them with the first argument being an instance of the particular object that the member function shall be associated with. In your case, you can fix this by first correctly declaring and assigning to func:
std::function<int (test&, int, int)> func;
// ...
func = &test::funcAB;
Then, the call side looks a bit different, too. Pass A as the first parameter here:
cout <<A.func(A,11,12) << endl;
Note that there is a different solution. You can leave the func declaration as it is and assign a lambda to it that captures this:
func = [this](int a, int b){ return funcAB(a, b); };
I can bind a private member function using a lambda. I'm struggling to write the equivalent using std::bind. This is my attempt, but it doesn't compile.
#include <functional>
class A {
private:
double foo(double x, double y);
public:
A();
std::function<double(double,double)> std_function;
};
A::A() {
// This works:
//std_function = [this](double x, double y){return foo(x,y);};
std_function = std::bind(&A::foo,this,std::placeholders::_1));
}
std_function is supposed to take 2 parameters, but you're only specifying one. Note that the placeholders are used for arguments to be bound when std_function is invoked later.
Change it to
std_function = std::bind(&A::foo, this, std::placeholders::_1, std::placeholders::_2);
I'm having trouble understanding function signatures and pointers.
struct myStruct
{
static void staticFunc(){};
void nonstaticFunc(){};
};
int main()
{
void (*p)(); // Pointer to function with signature void();
p = &myStruct::staticFunc; // Works fine
p = &myStruct::nonstaticFunc; // Type mismatch
}
My compiler says that the type of myStruct::nonstaticFunc() is void (myStruct::*)(), but isn't that the type of a pointer pointing to it?
I'm asking because when you create an std::function object you pass the function signature of the function you want it to point to, like:
std::function<void()> funcPtr; // Pointer to function with signature void()
not
std::function<void(*)()> funcPtr;
If I had to guess based on the pattern of void() I would say:
void myStruct::();
or
void (myStruct::)();
But this isn't right. I don't see why I should add an asterisk just because it's nonstatic as opposed to static. In other words, pointer void(* )() points to function with signature void(), and pointer void(myStruct::*)() points to function with signature what?
To me there seems to be a basic misunderstanding of what a member pointer is. For example if you have:
struct P2d {
double x, y;
};
the member pointer double P2d::*mp = &P2d::x; cannot point to the x coordinate of a specific P2d instance, it is instead a "pointer" to the name x: to get the double you will need to provide the P2d instance you're looking for... for example:
P2d p{10, 20};
printf("%.18g\n", p.*mp); // prints 10
The same applies to member functions... for example:
struct P2d {
double x, y;
double len() const {
return sqrt(x*x + y*y);
}
};
double (P2d::*f)() const = &P2d::len;
where f is not a pointer to a member function of a specific instance and it needs a this to be called with
printf("%.18g\n", (p.*f)());
f in other words is simply a "selector" of which of the const member functions of class P2d accepting no parameters and returning a double you are interested in. In this specific case (since there is only one member function compatible) such a selector could be stored using zero bits (the only possible value you can set that pointer to is &P2d::len).
Please don't feel ashamed for not understanding member pointers at first. They're indeed sort of "strange" and not many C++ programmers understand them.
To be honest they're also not really that useful: what is needed most often is instead a pointer to a method of a specific instance.
C++11 provides that with std::function wrapper and lambdas:
std::function<double()> g = [&](){ return p.len(); };
printf("%.18g\n", g()); // calls .len() on instance p
std::function<void()> funcPtr = std::bind(&myStruct::nonstaticFunc, obj);
Is how you store a member function in std::function. The member function must be called on a valid object.
If you want to delay the passing of an object until later, you can accomplish it like this:
#include <functional>
#include <iostream>
struct A {
void foo() { std::cout << "A::foo\n"; }
};
int main() {
using namespace std::placeholders;
std::function<void(A&)> f = std::bind(&A::foo, _1);
A a;
f(a);
return 0;
}
std::bind will take care of the details for you. std::function still must have the signature of a regular function as it's type parameter. But it can mask a member, if the object is made to appear as a parameter to the function.
Addenum:
For assigning into std::function, you don't even need std::bind for late binding of the object, so long as the prototype is correct:
std::function<void(A&)> f = &A::foo;
p = &myStruct::staticFunc; // Works fine
p = &myStruct::nonstaticFunc; // Type mismatch
Reason : A function-to-pointer conversion never applies to non-static member functions because an lvalue that refers to a non-static member function
cannot be obtained.
pointer void(* )() points to function with signature void(), and pointer void(myStruct::*)() points to function with signature what?
myStruct:: is to make sure that the non-static member function of struct myStruct is called (not of other structs, as shown below) :
struct myStruct
{
static void staticFunc(){};
void nonstaticFunc(){};
};
struct myStruct2
{
static void staticFunc(){};
void nonstaticFunc(){};
};
int main()
{
void (*p)(); // Pointer to function with signature void();
void (myStruct::*f)();
p = &myStruct::staticFunc; // Works fine
p = &myStruct2::staticFunc; // Works fine
f = &myStruct::nonstaticFunc; // Works fine
//f = &myStruct2::nonstaticFunc; // Error. Cannot convert 'void (myStruct2::*)()' to 'void (myStruct::*)()' in assignment
return 0;
}
When you use a pointer, std::function or std::bind to refer to a non-static member function (namely, "method" of class Foo), the first param must be a concrete object of class Foo, because non-static method must be called by a concrete object, not by Class.
More details: std::function and
std::bind.
The answer is in the doc.
Pointer to member declarator: the declaration S C::* D; declares D as
a pointer to non-static member of C of type determined by
decl-specifier-seq S.
struct C
{
void f(int n) { std::cout << n << '\n'; }
};
int main()
{
void (C::* p)(int) = &C::f; // pointer to member function f of class C
C c;
(c.*p)(1); // prints 1
C* cp = &c;
(cp->*p)(2); // prints 2
}
There are no function with signature void (). There are void (*)() for a function or void (foo::*)() for a method of foo. The asterisk is mandatory because it's a pointer to x. std::function has nothing to do with that.
Note: Your confusion is that void() is that same signature that void (*)(). Or even int() <=> int (*)(). Maybe you think that you can write int (foo::*) to have a method pointer. But this is a data member pointer because the parenthesis are optional, int (foo::*) <=> int foo::*.
To avoid such obscure syntax you need to write your pointer to function/member with the return type, the asterisk and his parameters.
Basically, I want a function pointer to be able to be called with default arguments. Take a look at the following:
#include <iostream>
using namespace std;
int function(int arg1 = 23)
{
printf("function called, arg1: %d\n", arg1);
return arg1 * 3;
}
template<typename Fn> int func(Fn f)
{
int v = 3;
f(); //error here 'error: too few arguments to function'
f(23); //this compiles just fine
return v;
}
int main() {
func(&function);
printf("test\n");
return 0;
}
Is there any way (trickery or otherwise) to be able to call a function with default arguments from a function pointer (or a template argument) without specifying the argument explicitly?
Yes There is a Good way. Function Object. I highly recommend you to see this link.
http://www.stanford.edu/class/cs106l/course-reader/Ch13_Functors.pdf
With std::bind. It returns a function object that calls the function with arguments that you passed to bind expression:
auto f = std::bind(&function, 23);
func(f);
I know how to declare int fn(double) inside of std::function (std::function<int(double)>). I know how to write a pointer-to-member-function (typedef int (A::*MemFn)(double d);). But how do i write a pointer-to-member-function with std::function?
Dummy code if you feel like compiling/testing
-edit- based on answers i think i'll just use the typedef and not bother with std::function
#include <cstdio>
#include <functional>
struct A{ int fn(double){ return 0; } };
int fn2(double){ return 0; }
typedef int (A::*MemFn)(double d);
typedef std::function<int(double)> MemFn2;
void Test(A*a, MemFn2 fn){
fn(1.2f);
}
void Test(A*a, MemFn fn){
(a->*fn)(1.2f);
}
int main(){
Test(new A, &A::fn);
Test(new A, &fn2);
}
std::function is perfectly capable of storing a member function pointer directly. However, you have to adjust the argument list appropriately. Member pointers must be called with an instance of the type (or a derived type). When putting them in a std::function, the first argument in the argument list is expected to be a pointer (or reference or smart-pointer) to the object type.
So, if I have the following class:
struct Type
{
public:
int Foo();
};
The correct syntax to store this member function in a std::function is:
std::function<int(Type&)> fooCaller = &Type::Foo;
If you want to preserve the argument list (in your case, int(double)), then you need to provide the instance outside of the function. This can be done via std::bind:
struct A{ int fn(double){ return 0; } };
A anInstance;
std::function<int(double)> fnCaller = std::bind(&A::fn, &anInstance, std::placeholders::_1);
Note that it is your responsibility to ensure that the object pointer you provide to std::bind remains alive so long as fnCaller is alive. If you return fnCaller to someone, and it has a pointer to a stack object, you're in trouble.
What's nice is that you could bind a shared_ptr (or any copyable smart pointer) as your object, thanks to how the function call mechanism is defined:
struct A{ int fn(double){ return 0; } };
auto anInstance = std::make_shared<A>();
std::function<int(double)> fnCaller = std::bind(&A::fn, anInstance, std::placeholders::_1);
Now you don't have to worry; the binder will continue to keep the object alive, since it stores a shared_ptr by value.
A member function is not a function. It is not itself anything you can call. All you can do is call a member function of an instance object. Only the pair of pointer-to-member-function and object constitutes a callable entity.
To bind an instance to a PTMF and obtain something callable, use bind:
#include <functional>
struct Foo
{
double bar(bool, char);
};
Foo x;
using namespace std::placeholders;
std::function<double(bool, char)> f = std::bind(&Foo::bar, x, _1, _2);
f(true, 'a'); //...
As with lambdas, bind expressions have an unknowable type, and the conversion to std::function (as well as the actual dispatch) is potentially expensive. If possible, it is preferable to use auto for the type of the bind expression.
One of the guidelines in Scott Meyer's Modern C++11 book is to avoid std::bind and always use a lambda closure instead:
struct A{ int fn(double){ return 0; } };
std::function<int(double)> f = [a = A{}](double x) mutable { return a.fn(x); };
The mutable is necessary here, as the capture a might potentially be changed by the function call (since A::fn is non-const).
You can use std::binder1st to bind member function to a class instance:
typedef std::binder1st<std::mem_fun1_t<int, A, double>> MemFn;
void Test(A* a, double d)
{
MemFn fn(std::mem_fun(&A::fn), a);
int nRetVal = fn(d);
}
int main()
{
Test(new A, 1.2f);
return 0;
}
If you can use Boost then you can use Boost.Bind. It's easily accomplished like this:
boost::bind(&MyClass::MemberFunction, pInstance, _1, _2)
Hopefully it's fairly self-explanatory. _1 and _2 are placeholders for parameters you can pass through to the function.