c ++ 11将std :: tuple解压缩为虚拟成员函数

问题描述 投票:6回答:1

全文:

我正在尝试构建一个看起来像这样的框架:

#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对我来说是新手,但仍然令人困惑,因此,非常明确的答案将不胜感激!

c++ c++11 templates variadic-templates
1个回答
7
投票
通常在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
© www.soinside.com 2019 - 2024. All rights reserved.