1.工程中合适使用模板,益处颇多,不管是软件自身版本升级亦或是系统升级还是跨平台,都可见一斑。废话不多说,直接贴代码:
#ifndef _INTERNAL_SDK_EVENT_MGR_H_
#define _INTERNAL_SDK_EVENT_MGR_H_
#include <map>
#include <memory>
#include <type_traits>
#include <vector>
namespace handle {
template <class C, class Type, class T, class... Args>
void Execute(const C &vec, Type T::* f, Args &&... args) {for (size_t i = 0; i < vec.size(); i++) {auto &&elem = vec[i];(elem->*f)(std::forward<Args>(args)...);}
}template <class C, class Type, class T, class... Args>
bool Dispatch(const C &vec, Type T::* f, Args &&... args) {for (size_t i = 0; i < vec.size(); i++) {auto &&elem = vec[i];if ((elem->*f)(std::forward<Args>(args)...)) {return true;}}return false;
}template <class C, class Type, class T, class... Args>
bool Check(const C &vec, Type T::* f, Args &&... args) {for (size_t i = 0; i < vec.size(); i++) {auto &&elem = vec[i];if (!(elem->*f)(std::forward<Args>(args)...)) {return false;}}return true;
}template <class T> class Manager : public std::vector<T> {
public:using _MyBase = std::vector<T>;Manager() = default;~Manager() = default;Manager(const Manager &) = delete;Manager &operator=(const Manager &) = delete;Manager(Manager &&) = default;Manager &operator=(Manager &&) = default;bool Register(T &&t, bool check_repetition = false) { if (!t) return false;if (check_repetition) {auto it = std::find(_MyBase::cbegin(), _MyBase::cend(), t);if (it != _MyBase::cend()) return false;}_MyBase::push_back(std::move(t));return true;}bool Register(const T &t, bool check_repetition = false) {if (!t) return false;if (check_repetition) {auto it = std::find(_MyBase::cbegin(), _MyBase::cend(), t);if (it != _MyBase::cend()) return false;}_MyBase::push_back(t);return true;}bool Unregister(const T &elem, bool just_unregister_first = true) {for (auto it = _MyBase::begin(); it != _MyBase::end();) {if (*it == elem) {it = _MyBase::erase(it);if (just_unregister_first)return true;} else {it++;}}return false;}const T &GetAt(int index) const { return _MyBase::at(index); }void RemoveAt(int index) { _MyBase::erase(_MyBase::begin() + index); }int GetSize() const { return _MyBase::size(); }template <class Type, class... Args> void Execute(Type f, Args &&... args) {return handle::Execute(*this, f, std::forward<Args>(args)...);}template <class Type, class... Args> bool Dispatch(Type f, Args &&... args) {return handle::Dispatch(*this, f, std::forward<Args>(args)...);}template <class Type, class... Args> bool Check(Type f, Args &&... args) {return handle::Check(*this, f, std::forward<Args>(args)...);}template <class Finder,std::enable_if_t<!std::is_convertible_v<Finder, T>, int> = 0>void Unregister(const Finder &finder, bool just_unregister_first = true) {for (auto it = _MyBase::begin(); it != _MyBase::end();) {if (finder(*it)) {it = _MyBase::erase(it);if (just_unregister_first)return;} else {it++;}}}
};} // namespace handleclass WndProviderMgr: public handle::Manager<std::unique_ptr<IReader_WndProvider>> {
public:IReader_WndProvider *GetWndProviderByName(const CFX_ByteString &bsName);
};#define DEFINE_READER_HANDLER_MGR(Type, FuncName) Type *FuncName()
#define DEFINE_HANDLER_MGR(Name) \DEFINE_READER_HANDLER_MGR(Name##Mgr, Name##Manager)
namespace reader {
template <class C, class F> bool Check(const C &vec, F f) {for (auto it = vec.cbegin(); it != vec.cend(); it++) {auto &&elem = *it;if (!f(elem)) {return false;}}return true;
}template <class C, class F> void Execute(const C &vec, F f) {for (auto it = vec.cbegin(); it != vec.cend(); it++) {auto &&elem = *it;f(elem);}
}template <class C, class F> bool Dispatch(const C &vec, F f) {for (auto it = vec.cbegin(); it != vec.cend(); it++) {auto &&elem = *it;if (f(elem)) {return true;}}return false;
}DEFINE_HANDLER_MGR(WndProvider);
} // namespace reader#endif
上面使用一种模板对抽象的用户层数据(函数)进行管理。