std::function as member, take functions to either member- or global functions
Mar 15, 2015 at 4:27pm UTC
hey guys,
I have a class called Button which has a function pointer i want to replace with std::function<>.
I can easily use std::function with non-member and member functions, but is it possible to use one std::function for both cases?
It currently looks like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
template <typename T>
class Button
{
public :
std::function<void (const T&)> func;
};
<functional>
class A
{
public :
void print() const // in A
{
std::cout << "Hallo A" << std::endl;
}
};
int main(void )
{
A a;
B<A> b;
b.func = &A::print;
b.func(a);
return 0;
}
Now i can use func to point to any member function of class T but i am not able to call non-member functions this way.
when changing the definition to this i can use non-member functions but member functions
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
class Button
{
public :
std::function<void ()> func;
};
void print() // global
{
std::cout << "Hallo" << std::endl;
}
int main(void )
{
B b;
b.func = &print;
b.func();
return 0;
}
How can i write the Button class that it can access both functions?
(of course with 2 instances of Button)
I hope you understand my question ._.
Last edited on Mar 15, 2015 at 4:33pm UTC
Mar 15, 2015 at 4:33pm UTC
is it possible to use one std::function for both cases?
Yes. That is the whole point of using std::function: To bind multiple different function types to a single object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
class Example
{
public :
void foo();
void bar(int x);
};
void glbl();
void call_it( std::function<void ()> func )
{
func();
}
int main()
{
Example a;
call_it( &glbl ); // glbl();
call_it( std::bind( &Example::foo, a ) ); // a.foo();
call_it( std::bind( &Example::bar, a, 6 ) ); // a.bar(6);
}
Mar 15, 2015 at 4:37pm UTC
awesome, std::bind was the missing piece!
thank you my friend :)
Mar 15, 2015 at 4:56pm UTC
Actually I think I screwed that up. That might be making a temporary copy of 'a' and not actually calling on the real 'a' object.
Pass by pointer instead:
1 2
call_it( std::bind( &Example::foo, &a ) ); // a.foo();
call_it( std::bind( &Example::bar, &a, 6 ) ); // a.bar(6);
I'm not 100% that my original post won't work... but I
am 100% sure that this edit will work.
Mar 15, 2015 at 5:09pm UTC
I confirm, you should use std::ref(a) or std::cref(a).
"The arguments to bind are copied or moved, and are
never passed by reference unless wrapped in std::ref
or std::cref ."
Topic archived. No new replies allowed.