我正在撰寫一個模板包裝函式,它可以應用于具有不同數量/型別的引數的函式。我有一些有效的代碼,但我正在嘗試將更多引數更改為模板引數。
作業代碼:
#include <iostream>
int func0(bool b) { return b ? 1 : 2; }
//There is a few more funcX...
template<typename ...ARGS>
int wrapper(int (*func)(ARGS...), ARGS... args) { return (*func)(args...) * 10; }
int wrappedFunc0(bool b) { return wrapper<bool>(func0, b); }
int main()
{
std::cout << wrappedFunc0(true) << std::endl;
return 0;
}
現在我int (*func)(ARGS...)也想成為一個模板引數。(這是出于性能原因。我希望將指標備份到包裝器中,因為我使用它的方式會阻止編譯器對其進行優化。)
這是我想出的(唯一的區別是我已將一個引數更改為模板引數。):
#include <iostream>
int func0(bool b) { return b ? 1 : 2; }
//There is a few more funcX...
template<typename ...ARGS, int (*FUNC)(ARGS...)>
int wrapper(ARGS... args) { return (*FUNC)(args...) * 10; }
int wrappedFunc0(bool b) { return wrapper<bool, func0>(b); }
int main()
{
std::cout << wrappedFunc0(true) << std::endl;
return 0;
}
這不編譯。表明:
<source>: In function 'int wrappedFunc0(bool)':
<source>:9:55: error: no matching function for call to 'wrapper<bool, func0>(bool&)'
9 | int wrappedFunc0(bool b) { return wrapper<bool, func0>(b); }
| ~~~~~~~~~~~~~~~~~~~~^~~
<source>:7:5: note: candidate: 'template<class ... ARGS, int (* FUNC)(ARGS ...)> int wrapper(ARGS ...)'
7 | int wrapper(ARGS... args) { return (*FUNC)(args...) * 10; }
| ^~~~~~~
<source>:7:5: note: template argument deduction/substitution failed:
<source>:9:55: error: type/value mismatch at argument 1 in template parameter list for 'template<class ... ARGS, int (* FUNC)(ARGS ...)> int wrapper(ARGS ...)'
9 | int wrappedFunc0(bool b) { return wrapper<bool, func0>(b); }
| ~~~~~~~~~~~~~~~~~~~~^~~
<source>:9:55: note: expected a type, got 'func0'
ASM generation compiler returned: 1
<source>: In function 'int wrappedFunc0(bool)':
<source>:9:55: error: no matching function for call to 'wrapper<bool, func0>(bool&)'
9 | int wrappedFunc0(bool b) { return wrapper<bool, func0>(b); }
| ~~~~~~~~~~~~~~~~~~~~^~~
<source>:7:5: note: candidate: 'template<class ... ARGS, int (* FUNC)(ARGS ...)> int wrapper(ARGS ...)'
7 | int wrapper(ARGS... args) { return (*FUNC)(args...) * 10; }
| ^~~~~~~
<source>:7:5: note: template argument deduction/substitution failed:
<source>:9:55: error: type/value mismatch at argument 1 in template parameter list for 'template<class ... ARGS, int (* FUNC)(ARGS ...)> int wrapper(ARGS ...)'
9 | int wrappedFunc0(bool b) { return wrapper<bool, func0>(b); }
| ~~~~~~~~~~~~~~~~~~~~^~~
<source>:9:55: note: expected a type, got 'func0'
Execution build compiler returned: 1
(鏈接到編譯器資源管理器)
對我來說,這看起來像是編譯器的問題,但 GCC 和 Clang 對此表示同意,所以也許不是。
無論如何,如何使用指向函式的模板化指標正確編譯此模板?
編輯:使用實體化函式模板解決重復標志編譯問題 我認為該問題的核心問題與我的相同,但是,它缺少一個解決方案,允許將指向函式的指標(不僅僅是它的型別)作為模板引數。
uj5u.com熱心網友回復:
這不起作用,因為 pack 引數(包括 的引數...)會消耗所有剩余的引數。它后面的所有引數都不能明確指定,必須推導。
通常你寫這樣的包裝器:
template <typename F, typename ...P>
int wrapper(F &&func, P &&... params)
{
return std::forward<F>(func)(std::forward<P>(params)...) * 10;
}
(如果該函式在包裝器內多次呼叫,則除最后一個呼叫之外的所有呼叫都不能使用std::forward.)
這將通過參考傳遞函式,這應該與使用函式指標完全相同,但我沒有理由相信它會阻止編譯器對其進行優化。
std::integral_constant<decltype(&func0), func0>{}您可以通過傳遞而不是強制將函式編碼在模板引數中func0,但我認為它不會改變任何東西。
uj5u.com熱心網友回復:
第二個片段無效,因為:
型別引數包不能在其自己的引數子句中展開。
從[temp.param]/17 開始:
如果模板引數是在其可選識別符號之前帶有省略號的型別引數,或者是宣告包([dcl.fct])的引數宣告,則模板引數是模板引數包。作為引數宣告的模板引數包,其型別包含一個或多個未擴展包,即為包擴展。...作為包擴展的模板引數包不應擴展在同一template-parameter-list 中宣告的模板引數包。
因此,請考慮以下無效示例:
template<typename... Ts, Ts... vals> struct mytuple {}; //invalid
上面的例子是無效的,因為模板型別引數包Ts不能在它自己的引數串列中展開。
出于同樣的原因,您的代碼示例無效。例如,您的第二個片段的簡化版本無法在 msvc 中編譯。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/459559.html
上一篇:沒有定義宏的代碼重復問題
下一篇:在java中決議陣列串列
