2011-08-04 151 views
14

我要尋找類似的東西:可變參數模板參數包擴大函數調用

template< typename T> 
void func(T t) 
{ 
} 

template< typename... Parms> 
void anyFunc(Parms... p) 
{ 
    func<Parms>(p)... ; //error 
    func(p)... ;   //error 
} 

如果參數組擴展另一個函數內部完成調用它的工作原理:

template< typename T> 
int some(T t) 
{} 

template< typename... Parms> 
void func(Parms ...p) 
{} 

template< typename... Parms> 
void somemore(Parms... p) 
{ 
    func(some(p)...); 
} 

int main() 
{ 
somemore(1,2,3,4,10,8,7, "Hallo"); 
} 

的參數包擴展也適用於基類初始值設定項列表。

是否有任何解決方案,也將工作的功能,將返回'空白'。上面的解決方法不會,而在參數列表中使用函數調用返回void無法工作。

任何想法?

+0

哈克的解決辦法是將函數調用與逗號操作結合起來(因此包擴展模式不會產生'void'),並使用某種僅僅「吃」其參數的虛擬函數。類似[this](http://ideone.com/fFyPT)。不過,懷疑這是你想要的。 :) – Vitus

回答

8

不幸的是,正如你注意到的那樣,擴展參數包只在解析器期望逗號分隔的條目列表的某些上下文中有效 - 逗號僅僅是語法分隔符而不是逗號操作符的上下文。這可以說是當前文本中的一個缺陷。

醜陋的解決方法:

func((some(p), 0)...); 

請注意,函數參數的計算順序,從而some調用的順序,是不確定的,所以你必須要小心任何副作用。

+0

通過在初始化程序列表中使用包擴展,可以輕鬆獲得以正確順序評估的函數。注意:g ++ 4.8.1有一個錯誤並且向後評估! – Klaus

+0

',0'的用途是什麼? –

+3

@ Peregring-lk:使省略號下的表達式(某些(p),0)具有非空類型 - 這是必需的,因爲需要一個有效的非空類型來傳入輔助函數func '。 – liori

5

怎麼樣一個小的輔助類:

template <typename Func, typename A, typename ...Args> struct Caller 
{ 
    static void call(Func & f, A && a, Args && ...args) 
    { 
    f(std::forward<A>(a)); 
    Caller<Func, Args...>::call(f, args...); 
    } 
}; 

template <typename Func, typename A> struct Caller<Func, A> 
{ 
    static void call(Func & f, A && a) 
    { 
    f(std::forward<A>(a)); 
    } 
}; 

template <typename Func, typename ...Args> 
void Call(Func & f, Args && ...args) 
{ 
    Caller<Func, Args...>::call(f, std::forward<Args>(args)...); 
} 

然後你就可以把你的客戶端代碼如下:

void foo(A); 
Call(foo, a1, a2, a3); 
+0

@Dolanor:感謝您的修復。對於這麼短的帖子,這是一個驚人的錯誤:-S –

+1

沒有問題。我需要努力實驗,爲什麼不分享更正? ;) – Dolanor

相關問題