我想在一些manager-class中存储任意数量的不同 类(所有共享指针)。不同的类必须从相同的CRTP接口类派生。最后,我希望能够遍历所有存储的类并调用接口的某些功能。我不想创建一个公共基类,我只想使用编译时的东西。
所以我在互联网上阅读了一些文章并一起偷了一些概念。现在我有一个可行的解决方案(我希望,我是C ++模板的新手!),但我认为,对于这样一个简单的"而言,这太过分了。需求。
你能帮助我优化(简化/缩小/修改)以下最小例子或提供更智能的解决方案吗? (没有提升,只有C ++ 11/14/17)
#include <iostream>
#include <tuple>
#include <memory>
template <class T_IMPLEMENTATION>
struct ISystem {
bool run(int i) { return static_cast<T_IMPLEMENTATION*>(this)->runImpl(i); }
};
struct SystemA : public ISystem<SystemA> {
friend ISystem<SystemA>;
private:
bool runImpl(int i) { std::cout << this << " A:" << i << std::endl; return i; };
};
struct SystemB : public ISystem<SystemB> {
friend ISystem<SystemB>;
private:
bool runImpl(int i) { std::cout << this << " B:" << i << std::endl; return i; };
};
template<typename... ARGS>
struct SystemManager {
template <int index, typename... Ts>
struct runSystem {
void operator()(std::tuple<Ts...>& t, int i) {
std::get<TUPLE_SIZE - index - 1>(t)->run(i++);
runSystem<index - 1, Ts...>{}(t, i);
}
};
template <typename... Ts>
struct runSystem<0, Ts...> {
void operator()(std::tuple<Ts...>& t, int i) {
std::get<TUPLE_SIZE - 1>(t)->run(i);
}
};
template <typename...SPTR_ARGS>
void addSystems(SPTR_ARGS...args) {
m_tupleSystems = std::make_tuple(args...);
}
void run() {
m_value = 0;
runSystem<TUPLE_SIZE - 1, std::shared_ptr<ISystem<ARGS>>...>{}(m_tupleSystems, m_value);
}
private:
using TUPLE_TYPE = std::tuple<std::shared_ptr<ISystem<ARGS>>...>;
static constexpr auto TUPLE_SIZE = std::tuple_size<TUPLE_TYPE>::value;
TUPLE_TYPE m_tupleSystems;
int m_value;
};
int main() {
auto sptrSystemA = std::make_shared<SystemA>();
auto sptrSystemB = std::make_shared<SystemB>();
SystemManager<SystemA, SystemB> oSystemManager;
oSystemManager.addSystems(sptrSystemA, sptrSystemB);
oSystemManager.run();
return 0;
}