全文:
我正在尝试构建一个看起来像这样的框架:
#include <tuple>
#include <memory>
using namespace std;
// this class allows user to call "run" without any args
class simulation_base{
public:
int run(){ execute_simulation_wrapped(); };
protected:
virtual int execute_simulation_wrapped(); {return 0;};
}
// this class funnels some stored inputs into a soon-to-be-overridden method
template <typename Ts...>
class simulation_wrapper : public simulation_base {
tuple<shared_ptr<Ts>... > stored_inputs;
public:
int execute_simulation_wrapped() {/* how do you call simulation method? */};
protected:
virtual int simulation(const Ts&...){return 0};
}
现在,我们可以使用该框架来定义几个可以模拟的简单类。
class jones_household : public simulation_wrapper< woman, girl, cat >{
int simulation(woman mrs_jones, girl mary, cat sniffles)
// mrs_jones and her daugther mary play with sniffles the cat
return 1;
}
}
class smith_household : public simulation_wrapper< man, dog >{
int simulation(man mr_smith, dog fido)
// mr_smith and his dog fido go for a walk
return 1;
}
}
然后建立这些可模拟家庭的多元宇宙...
smith_household uinverse_1_smiths;
smith_household uinverse_2_smiths;
jones_houshold uinverse_1_jones;
jones_houshold uinverse_2_jones;
// set the values of the stored_inputs (i.e. fido, sniffles etc.)
最后,我们要指出的是:我们希望能够编写一个与家用类型无关的函数,但仍然能够在模拟中调用run
:
void play_simulation(simulation_base& some_household){
// do some general stuff...
some_household.run();
}
总结: run
调用虚拟方法execute_simulation_wrapped
的相关模板实例,然后解压缩stored_inputs
并将其提供给虚拟simulation
函数,该函数具有针对每个函数的自定义实现家庭。
我想我应该问的问题:
所以,我想我已经完成了上面的大部分工作,但是我已经看了很长时间了[[很长时间,但是我仍然无法弄清楚simulation_wrapper::execute_simulation_wrapped
函数如何进行调用到simulation
并提供未打包的元组stored_inputs
作为参数包。
TMP对我来说是新手,但仍然令人困惑,因此,非常明确的答案将不胜感激!
index_sequence
的帮助下完成:template <typename... Ts>
class simulation_wrapper : public simulation_base
{
tuple<shared_ptr<Ts>... > stored_inputs{new Ts...};
public:
// MAGIC STARTS HERE
int execute_simulation_wrapped() { return execute_simulation_wrapped(std::make_index_sequence<sizeof...(Ts)>{}); }
private:
template <std::size_t... Is>
int execute_simulation_wrapped(std::index_sequence<Is...>) { return simulation(*std::get<Is>(stored_inputs)...); }
// MAGIC ENDS HERE
protected:
virtual int simulation(const Ts&...){return 0;};
};
如果需要index_sequence
,仅在C ++ 14之后才可用<utility>
,则可以使用以下实现:
template <std::size_t... Is> struct index_sequence {}; template <std::size_t N, std::size_t... Is> struct make_index_sequence_h : make_index_sequence_h<N - 1, N - 1, Is...> {}; template <std::size_t... Is> struct make_index_sequence_h<0, Is...> { using type = index_sequence<Is...>; }; template <std::size_t N> using make_index_sequence = typename make_index_sequence_h<N>::type;
DEMO