2014-09-29 79 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

相关问题