2014-04-03 52 views
1

我正在努力與可變模板的多繼承。可變模板和多繼承

這是我到目前爲止的代碼:

template <typename U> 
    class id_map { 
    public: 
    std::vector<U> vec_; 
}; 

現在我想初始化另一個類,從id_map繼承了多次,這樣的事情:

template<typename ... T> 
class constant_allkey_map : public id_map<T> ... { 
private: 
public: 
    template <typename U> 
    void push_back(U i) { 
     id_map<U>::vec_.push_back(i); 
    } 
}; 

這工作,我可以訪問它只是很好:

constant_allkey_map<int, long> cakm; 
cakm.push_back<int>(1); 

當我嘗試這樣的事情時失敗:

constant_allkey_map<int, int> cakm; 

錯誤

"duplicate base type id_map<int> invalid". 

我做了一些閱讀,似乎我應該id_map模板與id參數擴展:

template <size_t i_, typename U> 
class id_map ... 

,但我不知道如何通過該身份證中的繼承部分:

template<typename ... T> 
class constant_allkey_map : public id_map<T> ... { 

可以meone請幫助我?如果我完全錯了,請指出我的方向是正確的?

+0

你期待'cakm.push_back(1);'當'cakm是'constant_allkey_map ''時要做什麼? – Casey

+0

我會很高興與cakm.push_back <0>(1); cakm.push_back <1>(1);就像tupple被使用,但不知道如何實現......基本上這是我的問題 – Paladin

回答

6

我不認爲繼承是正確的。爲此,我提出以下的方法來實現你想要什麼:

#include <tuple> 
#include <vector> 

template <typename U> 
class id_map 
{ 
public: 
    typedef U value_type; 

public: 
    std::vector<U> vec_; 
}; 

template<typename... T> 
class constant_allkey_map 
{ 
private: 
    typedef std::tuple<id_map<T>...> tuple_t; 

public: 
    template< 
    std::size_t Idx, 
    typename U = typename std::tuple_element<Idx, tuple_t>::type::value_type 
    > 
    void push_back(U x) 
    { 
    std::get<Idx>(maps_).vec_.push_back(x); 
    } 

    template< 
    std::size_t Idx, 
    typename U = typename std::tuple_element<Idx, tuple_t>::type::value_type 
    > 
    U get(int i) const 
    { 
    return std::get<Idx>(maps_).vec_[i]; 
    } 

private: 
    tuple_t maps_; 
}; 

用法很簡單:

#include <iostream> 

int main(int, char**) 
{ 
    constant_allkey_map<int, long> cakm; 
    cakm.push_back<0>(1); 
    cakm.push_back<0>(3); 
    cakm.push_back<1>(2); 
    cakm.push_back<1>(4); 

    std::cout << cakm.get<0>(0) << std::endl; 
    std::cout << cakm.get<1>(0) << std::endl; 
    std::cout << cakm.get<0>(1) << std::endl; 
    std::cout << cakm.get<1>(1) << std::endl; 
} 

這裏有一個live example.

基本上只是讓std::tuple做骯髒的工作您。你甚至可以這樣做:

template<typename... T> 
using constant_allkey_map = std::tuple<std::vector<T>...>; 

並直接使用std :: get。