2014-05-13 28 views
7

考慮我有一個參數int...的可變參數模板。例如,一個這樣的功能:添加參數包擴展的所有參數

template<int... t> 
int add(){ 
    return t... + ??? 
} 

所有的方法應該做的就是添加所有參數。使用遞歸可變參數模板可以輕鬆實現。但是,是否也可以使用參數包擴展來表達這個(或類似使用其他二元運算符來聚合所有模板參數)?

+0

不,只要做到這一點,它可以輕鬆實現。 –

+0

好吧,我只是認爲它可能會更容易,更容易理解與參數包擴展:) – gexicide

+2

其他解決方案的問題是他們計算添加的執行時間。 –

回答

18

是的,使用我從休息室的@Xeo中學到的技巧。我最初使用它來製作一個可變的「打印」模板功能。

#include <iostream> 

template<int... ints> 
int add() 
{ 
    int result = 0; 
    using expand_variadic_pack = int[]; // dirty trick, see below 
    (void)expand_variadic_pack{0, ((result += ints), void(), 0)... }; 
    // first void: silence variable unused warning 
    // uses braced-init-list initialization rules, which evaluates 
    // the elements inside a braced-init-list IN ORDER, to repetetively 
    // execute a certain operation 
    // second void is to prevent malicious "operator," overloads, which 
    // cannot exist for void types 
    // 0 at the end is to handle empty variadic pack (zero-size array initializer is illegal. 
    return result; 
} 

int main() 
{ 
    std::cout << add<1,2,3,4>() << '\n'; 
} 

這個工程上有不俗的C++ 11的支持每一個編譯器(GCC 4.8+,鐺3.2+,MSVS2013,...)

+8

不確定是否要大笑或哭泣 –

+0

@Lightness您肯定在C++中濫用過表達式的副作用。 – rubenvb

+0

當然! –

6

它使用Lambda和std::accumulate一個可能的變體:

#include <array> 
#include <numeric> 

template <int... t> 
int add() 
{ 
    return [](const std::array<int, sizeof...(t)>& a) 
    { 
     return std::accumulate(a.begin(), a.end(), 0); 
    }({t...}); 
} 
+1

這個看起來很乾淨,更不用說黑客!不幸的是,計算在編譯時不太可能被優化。 –