[英]c++11 unpack std::tuple into virtual member function
完整的故事:
我正在嘗試構建一個看起來有點像這樣的框架:
#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
的幫助下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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.