首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c++11解压缩std::元组为虚拟成员函数

c++11解压缩std::元组为虚拟成员函数
EN

Stack Overflow用户
提问于 2014-12-18 14:44:10
回答 1查看 627关注 0票数 6

全文:

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

代码语言:javascript
复制
#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};
}

现在,我们可以使用框架来定义几个简单的类,这些类可以被模拟。

代码语言:javascript
复制
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;
    }
}

然后建立一个多宇宙的模拟家庭..。

代码语言:javascript
复制
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

代码语言:javascript
复制
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对我来说是新的,仍然是完全混乱的,所以非常明确的答案将是非常感谢的!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-18 14:55:39

这通常是在index_sequence的帮助下完成的

代码语言:javascript
复制
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,这在<utility>中只有在C++14之后才可用,那么您可以使用以下实现:

代码语言:javascript
复制
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

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27549127

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档