std::function as member, take functions to either member- or global functions

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
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);
}
awesome, std::bind was the missing piece!
thank you my friend :)
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.
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.