2014-01-28 185 views
3

可變參數變量初始化我有,我想從另一個B類可變參數模板

頭看起來像調用模板函數模板類答:

template<typename... T> class A 
{ 
public: 
    A(); 
    void get(type_X params); 
private: 
    B b_; 
}; 

和.HXX:

template<typename... T> void A<T...>::get(type_X params) 
{ 
    /*here lies my problem*/ 
    T... variable; // just like we would do string s; 
        // and pass it to a function f(string& s) to assign it 
    b_.get(params, variable...); 
    /* do something with updated value of variable */ 
} 

其中構件B_(類B)具有模板函數得到看起來像

template<typename... T> int B<T...>::get(type_X params, const T&... variable) 
{ 
    /* change variable, just like we would assign a new value to a string& */ 
    return 0; 
} 

我不知道如何初始化(如果可能)我的「T ...」對象作爲模板函數B :: get的參數給出。

感謝您的幫助

回答

3

首先,指數機器在編譯時創建整數指數的包:

template< std::size_t... Ns > 
struct indices { 
    typedef indices< Ns..., sizeof...(Ns) > next; 
}; 

template< std::size_t N > 
struct make_indices { 
    typedef typename make_indices< N - 1 >::type::next type; 
}; 

template<> 
struct make_indices<0> { 
    typedef indices<> type; 
}; 

現在,你可以創建對象的數組:

T vars[] = { T()... }; 

接下來,您需要一個輔助函數來創建一個上下文,您可以在其中推導出整數包。事情是這樣的:

template<typename... T, T, size_t... I> 
int helper(type_X params, T* arr, indices<I...>) 
{ 
    return b_.get(params, arr[I]...); 
} 

對於arr參數你通過你以前創建的陣列vars和最後一個傳遞make_indices<sizeof...(T)>::type()

希望有所幫助。

+0

其實我需要檢索修改的對象變量,這不是明顯的在我的崗位我要編輯它。 – Thibaut

+0

您的答案使我的代碼編譯,但如果我理解正確,這不允許我檢索更新的T ...對象,我可以在A :: get範圍中使用? – Thibaut

+0

我相應地改變了我的答案。希望適合您的需求。 – jrok

1

首先,這是無效的語法:

T... variable; 

要做到這樣的事情,你需要創建一個元組:

std::tuple<T...> variable; 

,然後您使用的技術來調用一個與該元組成員作爲參數函數:

"unpacking" a tuple to call a matching function pointer Pass tuple's content as variadic function arguments How do I expand a tuple into variadic template function's arguments?

+0

是的,我知道這是無效的,我想要做類似的事情。但是,我甚至不知道如果存在的話。 元組似乎工作,但我告訴我的羅設計是不正確的,但由於反正這是我暴露出來的問題的解決方案。 – Thibaut

+0

使用你的元組讓我解決我的問題_theoricaly_:'對不起,沒有實現:不能展開「T ......」成固定長度的參數list' :)我需要一個新的編譯器... – Thibaut

+0

是的,你這樣做。或者至少是新的標準庫,因爲元組的參數列表不應該是固定的長度。 –

0

以下可以幫助你:

#if 1 // Not in C++11 
// Helper class to be able to use expansion of std::get<Index>(tuple) 
template <int... Is> struct index_sequence {}; 

// Following create index_sequence<0, 1, 2, .., sizeof...(Is) - 1> 
template <int Index, int... Is> 
struct make_index_sequence { // recursively build a sequence of indices 
    typedef typename make_index_sequence<Index - 1, Index -1, Is...>::type type; 
}; 

template <int... Is> 
struct make_index_sequence<0, Is...> { // stop the recursion when 0 is reached 
    typedef index_sequence<Is...> type; 
}; 
#endif 

template<typename... Ts> class A 
{ 
public: 
    void get(type_X params) 
    { 
     std::tuple<Ts...> t; 
     a.get(params, t, make_index_sequence<sizeof...(Ts)>()); 
    } 
private: 
    template<std::size_t ... Is> 
    void get(type_X params, std::tuple<Ts...>& t, index_sequence<Is...>) 
    { 
     b_.get(params, std::get<Is>(t)...); 
    } 

private: 
    B b_; 
};