Вы можете рассмотреть вариант класса на основе политик . Для этого мы определяем как шаблон функции * Variadi c, execute()
, так и шаблон класса HandlerHolder
, который наследуется от Handler
и переопределяет функцию-член updateFlags()
:
template<typename FlagUpdater, typename... FlagUpdaters>
void execute(Data_t& data) {
execute<FlagUpdater>(data);
if constexpr (sizeof...(FlagUpdaters))
execute<FlagUpdaters...>(data);
}
template<typename... FlagUpdaters>
class HandlerHolder final: public Handler {
public:
void updateFlags() override {
if constexpr (sizeof...(FlagUpdaters))
execute<FlagUpdaters...>(dbdata_);
}
};
В этот вариант c шаблона классов, HandlerHolder
, вы можете передавать классы (т. Е. Политики) в качестве аргументов шаблона, которые являются вызываемыми, и устанавливать соответствующие флаги. Оператор вызова функции (т.е. operator()
) этих классов политики вызывается в его переопределенной функции-члене updateFlags()
.
Затем вы должны определить классы политики, например:
struct AFlagSetter {
void operator()(Data_t& dbdata) const {
dbdata.flagA = 1;
}
};
struct BFlagSetter {
void operator()(Data_t& dbdata) const {
dbdata.flagB = 1;
}
};
struct CFlagSetter {
void operator()(Data_t& dbdata) const {
dbdata.flagC = 1;
}
};
Обратите внимание, что вы также можете легко определить политики для очистки флагов, например:
struct CFlagClearer {
void operator()(Data_t& dbdata) const {
dbdata.flagC = 0;
}
};
С помощью псевдонимов типов вы можете ввести имена типов для обработчиков, которые вы искали:
using ACHandler = HandlerHolder<AFlagSetter, BFlagSetter>;
using ABCHandler = HandlerHolder<AFlagSetter, BFlagSetter, CFlagSetter>;