2017-07-27 137 views
0

我想在一個可變參數模板中使用一個函數作爲參數,爲什麼下面不起作用?我如何使它工作?Variadic模板,函數作爲參數

template<typename F, typename... Args> 
F test(F f, const Args&&... args) { 
return f(std::forward<Args>(args)...); 
} 

int simple(int i) { 
    return i; 
} 


int main() 
{ 
    std::cout << test(simple, 2); // error, 'std::forward': none of the 2 overloads could convert all the argument types 
} 

回答

3

有幾個與你的代碼的問題。

首先,您應該使用轉發參考,因此您需要將const Args&&...更改爲Args&&...

然後,test不必返回F。所以在這裏使用decltype(auto)是合理的。

除此之外,轉發f也是有意義的。

固定的版本可能是這樣的:

template<typename F, typename... Args> 
decltype(auto) test(F&& f, Args&&... args) { 
    return std::forward<F>(f)(std::forward<Args>(args)...); 
} 

WANDBOX EXAMPLE

+0

爲什麼,當我添加了「測試」功能和「簡單」的功能基本類中,「測試」,作爲公共職能,並在主要做: 測試儀t; std :: cout << t.test(t.simple,2); 它不再有效,它說它找不到匹配的重載函數,而Tester ::簡單的非標準語法;使用&... – Alexander

+0

@Alexander很快,因爲'simple'成爲一個成員函數。你不能將成員函數傳遞給上面寫的'test'函數。至少,你必須提供一個調用成員函數的實例。查看'std :: invoke'獲取更多詳細信息:http://en.cppreference.com/w/cpp/utility/functional/invoke –

0

第一個問題是返回類型。您的test函數返回F這是一個函數指針。改爲將其更改爲auto以自動推斷返回類型。

第二個問題是std::forward需要一個非const引用。

您可以使用尾隨返回類型:

template<typename F, typename... Args> 
auto test(F f, Args&&... args) -> decltype(f(std::forward<Args>(args)...)) { 
    return f(std::forward<Args>(args)...); 
} 

decltype(auto)(C++ 14必需)是一個簡單的解決方案:

template<typename F, typename... Args> 
decltype(auto) test(F f, Args&&... args) { 
    return f(std::forward<Args>(args)...); 
} 
相關問題