2016-12-23 115 views
4

所以我一直在嘗試使用可變參數模板來構造出更方便的子類型的對象,但是我很難讓它做到我想要的。Variadic模板函數調用

template<class ...Functor> 
struct SeqMethod:public Functor...{ 
    template<class F> 
    void call(F& a){ 
    F::operator()(); 
    } 
    template<class F,class ... funcs> 
    void call(){ 
    F::operator()(); 

    call<funcs...>(); 
    } 
    public: 
    void operator()(){ 
    call<Functor...>(); 
    } 
}; 

這不是有效的語法,所以有這一點。

理想情況下,我想能夠使用這樣的事情

class A{ 
public: 
    void operator()(){ 
    std::cout<<"A"; 
    } 
}; 
class B{ 
public: 
    void operator()(){ 
    std::cout<<"B"; 
    } 
}; 

class C:public SeqMethod<A,B>{}; 

在這種情況下應該輸出「AB」,一般適用於合成行爲在一起。

回答

2

做到這一點,最簡單的方法是用C++ 17的fold expressions

template<class ...Functor> 
struct SeqMethod:public Functor...{ 

public: 
    void operator()(){ 
     (Functor::operator()(),...); 
    } 
}; 

class A{ 
public: 
    void operator()(){ 
     std::cout<<"A"; 
    } 
}; 
class B{ 
public: 
    void operator()(){ 
     std::cout<<"B"; 
    } 
}; 

class C:public SeqMethod<A,B>{}; 

int main() 
{ 
    C c; 
    c(); 
    return 0; 
} 

輸出(測試用gcc 6.2):

AB 
+0

這是偉大的,我真的很感激這個選項,但我的工作在某些平臺上,其C++編譯器是有點過時,所以因爲其他選項(初始化列表黑客)是有點容易得的就支持而言。 – jaked122

4

您實際上並不需要任何call成員函數。
相反,你可以做到這一點在C++ 11/C++ 14:

template<class ...Functor> 
struct SeqMethod:public Functor...{ 
    public: 
    void operator()(){ 
     int _[] = { (Functor::operator()(), 0)... }; 
     return void(_); 
    } 
}; 

它遵循最小,工作示例:

#include<iostream> 

template<class ...Functor> 
struct SeqMethod:public Functor...{ 
    public: 
    void operator()(){ 
    int _[] = { (Functor::operator()(), 0)... }; 
    return void(_); 
    } 
}; 

class A{ 
public: 
    void operator()(){ 
    std::cout<<"A"; 
    } 
}; 
class B{ 
public: 
    void operator()(){ 
    std::cout<<"B"; 
    } 
}; 

class C:public SeqMethod<A,B>{}; 

int main() { 
    C c; 
    c(); 
}