Hay, I wanted to clear my head on the topic of C++ events. There's sigslot, boost::signal, etc. I would still want to wrap any of those so it would be easier for myself to navigate/modify. So I came up with this example to try and weed it out. Trying to figure out the best way to propagate up events.

Does anybody have any comments, criticisms or improvements?

I wonder if the syntax could get any easier. I'm not fond of having to use boost::bind in the syntax with _1, but I guess that's the only way it could work in C++. At least, without macros?

Thanks

This code should run.

Skip to main():

Code:
#include <iostream>
#include <vector>

#include <boost/bind.hpp>
#include <boost/function.hpp>

namespace Framework
{
	template<typename T>
	class Event
	{
	private:
		std::vector<T> list;

	public:
		template<typename A1>
		Event<T>& operator()(A1& a1)
		{
			//std::cout << &list << ": Should be bigger than zero: " << this->list.size() << std::endl;

			for(std::vector<T>::const_iterator i = this->list.begin(), l = this->list.end(); i != l; ++i)
			{
				(*i)(a1);
			}

			return *this;
		}

		Event<T>& operator+(T& t)
		{
			//std::cout << &list << ": Increased" << std::endl;

			this->list.push_back(t);

			return *this;
		}

		Event<T>& operator+=(T& t)
		{
			return this->operator+(t);
		}

		template<typename A>
		Event<T>& operator+=(A& a)
		{
			return this->operator+(T(a));
		}
	};
}

class Table
{
public: 
	typedef Framework::Event<boost::function1<void, Table> > Event;

	Event ChangeEvent;

	// example
	void UpdateSomething()
	{
		this->ChangeEvent(*this);
	}

public:
	unsigned int id;
};

class Site
{
public: 
	typedef Framework::Event<boost::function1<void, Site> > Event;

	Table::Event AddTableEvent;
	Table::Event ChangeTableEvent;

	Site()
	{
		
	}

	// example
	Table UpdateSomething()
	{
		Table table;
		table.id = 1;

		table.ChangeEvent += this->ChangeTableEvent; // attach event handlers

		this->AddTableEvent(table);
		
		return table;
	}
};

class Application
{
public: 
	Site::Event AddSiteEvent;
	Site::Event ChangeSiteEvent;

	// example
	Site UpdateSomething()
	{	
		Site site;

		site.AddTableEvent += boost::bind(&Application::OnAddTable, this, _1);
		site.ChangeTableEvent += boost::bind(&Application::OnChangeTable, this, _1);

		return site;
	}

	/*
	* Callbacks
	*/

	void OnAddTable(Table& table)
	{
		std::cout << "Added: " << table.id << std::endl;
	}

	void OnChangeTable(Table& table)
	{
		std::cout << "Changed: " << table.id << std::endl;
	}
};


int main(int argc, char* argv[])
{
	Application app;

	Site& site = app.UpdateSomething();

	Table& table = site.UpdateSomething();

	table.UpdateSomething();

	std::cout << "End" << std::endl;

	std::cin.get();

	return 0;
}
Output:

Added: 1
Changed: 1
End