c++ - delegation

Does c++ have delegates? No! It's not necessary at all, it's not necessary at all. Because there is a better way. The compiler doesn't need it, and it's a waste for the compiler. So is this implementation still necessary? have! Otherwise, how can I let you paddle and dawdling in water articles.

The delegate in C# is a kind of function pointer in C++. The grammar is written in sand sculptures, and it's so weird. At that time, I saw this function followed by -> points to, .* when this kind of thing. . What a sand sculpture! !

auto fun(int a, char b)-> int; //表示返回int类型  

Specifies the returned type and nothing more. This stuff is written by people. . . is that useful? it works. However, it may not be used.

Here is the official explanation:

So, will it be used in commissioning? meeting.

This is an open source commission: I won't explain it, if you understand it, you may understand it at a glance, and if you don't understand it, you will understand it slowly.



#include <mutex>
#include <list>
#include <vector>
#include <memory>


template<typename>
class Delegate;

namespace DelegateImpl
{
template <typename TReturnType, typename... TArgs>
struct Invoker
{
	using ReturnType = std::vector<TReturnType>;

	public:
		static ReturnType Invoke(Delegate<TReturnType(TArgs...)> &delegate, TArgs... params)
		{
			std::lock_guard<std::mutex> lock(delegate.mMutex);
			ReturnType returnValues;

			for (const auto &functionPtr : delegate.mFunctionList)
			{
				returnValues.push_back((*functionPtr)(params...));
			}

			return returnValues;
		}
};

template <typename... TArgs>
struct Invoker<void, TArgs...>
{
	using ReturnType = void;

	public:
		static void Invoke(Delegate<void(TArgs...)> &delegate, TArgs... params)
		{
			std::lock_guard<std::mutex> lock(delegate.mMutex);

			for (const auto &functionPtr : delegate.mFunctionList)
			{
				(*functionPtr)(params...);
			}
		}
};
}

template<typename TReturnType, typename... TArgs>
class Delegate<TReturnType(TArgs...)>
{
	using Invoker = DelegateImpl::Invoker<TReturnType, TArgs...>;
	using functionType = std::function<TReturnType(TArgs...)>;

	friend Invoker;

	public:
		Delegate() {}
		~Delegate() {}

		Delegate(const Delegate&) = delete;
		const Delegate& operator =(const Delegate&) = delete;

		Delegate& Connect(const functionType &function)
		{
			std::lock_guard<std::mutex> lock(this->mMutex);

			this->mFunctionList.push_back(std::make_shared<functionType>(function));

			return *this;
		}

		Delegate& Remove(const functionType &function)
		{
			std::lock_guard<std::mutex> lock(this->mMutex);

			this->mFunctionList.remove_if([&](std::shared_ptr<functionType> &functionPtr)
			{
				return Hash(function) == Hash(*functionPtr);
			});

			return *this;
		}

		inline typename Invoker::ReturnType Invoke(TArgs... args)
		{
			return Invoker::Invoke(*this, args...);
		}

		Delegate& Clear()
		{
			std::lock_guard<std::mutex> lock(this->mMutex);

			this->mFunctionList.clear();

			return *this;
		}

		inline Delegate& operator +=(const functionType &function)
		{
			return Connect(function);
		}

		inline Delegate& operator -=(const functionType &function)
		{
			return Remove(function);
		}

		inline typename Invoker::ReturnType operator ()(TArgs... args)
		{
			return Invoker::Invoke(*this, args...);
		} 

	private:
		std::mutex mMutex;
		std::list<std::shared_ptr<functionType>> mFunctionList;

		inline constexpr size_t Hash(const functionType &function) const
		{
			return function.target_type().hash_code();
		}
};

Guess you like

Origin blog.csdn.net/qq_36912885/article/details/124379803