2014-09-29 91 views
2

我正在嘗試使用可變參數模板進行類構成。這個想法是Composer類簡單地聚合了一些變量並將函數調用轉發給所有實例化的變量。如何擴展基類的參數包和每個成員函數的調用?

首先我使用以下簡單包裝類:

template< typename T > 
struct WrapperType 
{ 
    typedef T wrapped_type; 
    typedef typename wrapped_type::value_type value_type; 
    wrapped_type wrapee_; 

    WrapperType() : wrapee_{} 
    {} 
}; 

這是使用具有以下Composer類,它希望從WrapperType實例化在參數包Args每種類型的派生:

template< typename... Args > 
struct Composer : public WrapperType<Args>... 
{ 
    Composer() : WrapperType<Args>{}... 
    {} 

    void display() 
    { 
     ((WrapperType<Args>...)::wrapee_).display(); // HOW? 
    } 
}; 

假設每個包裝類型都有一個display()成員函數,我怎樣才能爲參數包中的每個類型調用display()函數?

I.E.如果我有:

Composer< T1, T2, T3 > myComposer{}; 
myComposer.display(); 

我想myComposer.display()呼籲display()T1T2T3

+0

[爲什麼參數包擴展如此有限?](http://stackoverflow.com/questions/24316654/why-parameter-pack-expansion-is-so-limited) – Pradhan 2014-09-29 18:32:13

回答

5

只有幾個上下文,其中包擴展可能發生(第14.5.3節[temp.variadic]/p4)。您不能創建從一個函數調用包膨脹,但你可以數組初始化名單內即展開:

void display() 
{ 
    int t[] = { 0, ((void)WrapperType<Args>::wrapee_.display(), 1)... }; 
} 

DEMO

,或者,你可以使用遞歸,擴大了包在模板參數列表

void display() 
{ 
    call<Args...>(); 
} 

template <typename T, typename... Ts> 
void call() 
{ 
    WrapperType<T>::wrapee_.display(); 
    call<Ts...>(); 
} 

template <typename... Ts> 
auto call() -> typename std::enable_if<sizeof...(Ts) == 0>::type 
{ 
} 

DEMO 2

+0

謝謝,看起來很優雅。我正在考慮將參數包轉換爲boost :: mpl :: vector,並使用boost :: mpl :: for_each - 但我認爲這樣更乾淨。 – mark 2014-09-29 18:59:17

相關問題