How to distinguish between std:: function

I want to realize C# style delegate.

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
class Object{};
class EventArgs{};

#define delegate                            typedef
#define event_global(globalfun)             std::bind(&globalfun, std::placeholders::_1, std::placeholders::_2)
#define event_member(object, memberfun)     std::bind(&memberfun, &object, std::placeholders::_1, std::placeholders::_2)

template<typename... args>
class RoutedEvent
{
protected:
    std::vector<std::function<void(args...)>> vecEvents;

public:
    // 添加回调函数
    void operator +=(const std::function<void(args...)> &event)
    {
        vecEvents.push_back( event );
    }

    // 操作函数
    void RaiseEvent(args... param)
    {
        for( size_t i = 0; i < vecEvents.size(); i++ )
        {
            vecEvents[i](param...);
        }
    }
};

void MouseDown(Object* object, EventArgs* arg)
{
    cout << "Global MouseDown" << endl;
}

struct Test
{
    void MouseDown(Object* object, EventArgs* arg)
    {
        cout << "Member MouseDown" << endl;
    }
};

delegate RoutedEvent<Object*, EventArgs*> KeyEventHandler;


void main(int argc, char* argv[])
{
    Object object;
    EventArgs arg;
    Test test;
    
    KeyEventHandler KeyDown;
    KeyDown += event_global(MouseDown);
    KeyDown += event_member(test, Test::MouseDown);
    KeyDown.RaiseEvent( &object, &arg );

    system("pause");
}


I want to realize operator -=。The problem is how to distinct the two std::function object is equal?

My enalish is poor.
Thanks a lot!
closed account (2UD8vCM9)
I might be misunderstanding what you are asking, but I hope this is what you want.

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <Windows.h>
#include <iostream>
#include <conio.h>

using namespace std;

int main()
{
	while (true) 
	{ //Infinite Loop Start
		if (_kbhit() > 0) //If 1 or more keys are pressed on keyboard
		{ //If Start
			if (GetAsyncKeyState(VK_DOWN)) //If down arrow key is pressed
			{
				cout << "Key Down is Pressed.\n";
				Sleep(5); //Sleep 5 seconds so we don't check too fast and use too much processing power
			}

			if (GetAsyncKeyState(VK_UP)) //If down arrow key is pressed
			{
				cout << "Key Up is Pressed.\n";
				Sleep(5); //Sleep 5 seconds so we don't check too fast and use too much processing power
			}

			if (GetAsyncKeyState(VK_LEFT)) //If down arrow key is pressed
			{
				cout << "Key Left is Pressed.\n";
				Sleep(5); //Sleep 5 seconds so we don't check too fast and use too much processing power
			}

			if (GetAsyncKeyState(VK_RIGHT)) //If right arrow key is pressed
			{
				cout << "Key Right is Pressed.\n";
				Sleep(5); //Sleep 5 seconds so we don't check too fast and use too much processing power
			}
		} //If End

		if (GetAsyncKeyState(VK_LBUTTON)) //If left mouse is pressed
		{
			cout << "Left Mouse Click is Pressed.\n";
			Sleep(5); //Sleep 5 seconds so we don't check too fast and use too much processing power
		}
	} //Infinite Loop End


	return 0;
}


Link to Virtual Key Codes:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx

Edit: Sorry I am tired and realize I completely misread question after reading Cubbi's response
Last edited on
In some cases, you could use function::target_type and function::target to tell if two std::functions are holding the same thing,
http://en.cppreference.com/w/cpp/utility/functional/function/target but it's not really possible in general case.

Why not use a proven library, like boost? http://www.boost.org/doc/libs/release/doc/html/signals2.html

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <boost/signals2.hpp>

struct Object {int n;};
struct EventArgs {int n;};

void MouseDown(const Object& object, const EventArgs& arg)
{
    std::cout << "Global MouseDown: object = " << object.n
              << " arg = " << arg.n << '\n';
}

struct Test
{
    void MouseDown(const Object& object, const EventArgs& arg)
    {
        std::cout << "Member MouseDown: object = " << object.n
                  << " arg = " << arg.n << '\n';
    }
};

typedef boost::signals2::signal<void(const Object&, const EventArgs&)> KeyEventH

int main() // main does not return void!
{
    using std::placeholders::_1;
    using std::placeholders::_2;
    Object object = {1};
    EventArgs arg = {2};
    Test test;

    KeyEventHandler KeyDown;
    KeyDown.connect(MouseDown); // 1
    auto c = KeyDown.connect(std::bind(&Test::MouseDown, &test, _1, _2)); // 2
    KeyDown.connect(3, std::bind(&Test::MouseDown, &test, _1, _2)); //3
    std::cout << "keydown #1\n";
    KeyDown(object, arg);

    // if you have an EqualityComparable object. you can delete it just so
    KeyDown.disconnect(MouseDown); // disconnects #1
    std::cout << "keydown #2\n";
    KeyDown(object, arg);

    // if you connected using a group id, disconnect the group
    KeyDown.disconnect(3); // disconnects #3
    std::cout << "keydown #3\n";
    KeyDown(object, arg);

    // if you kept the connection object, disconnect using that
    c.disconnect(); // disconnects #2
    std::cout << "keydown #4\n";
    KeyDown(object, arg);
}



keydown #1
Member MouseDown: object = 1 arg = 2
Global MouseDown: object = 1 arg = 2
Member MouseDown: object = 1 arg = 2
keydown #2
Member MouseDown: object = 1 arg = 2
Member MouseDown: object = 1 arg = 2
keydown #3
Member MouseDown: object = 1 arg = 2
keydown #4
Last edited on
You mentioned the signal I was also considered, but I want to achieve a similar to the WPF interface library, I want to keep the consistency and the grammar as far as possible.

The link you gived me is very useful.

Thank you very much for your reply!
Last edited on
Topic archived. No new replies allowed.