我正在嘗試使用一個接受 std::function 的模板,但模板引數推導失敗。
double foo(){
return 2.3;
}
template <typename V>
void funcC (V (*fptr)()){
std::cout << "C function's value is\"" << fptr() << '\"' << std::endl;
}
template <typename V>
void funcCxx (std::function<V()> fptr){
std::cout << "C function's value is\"" << fptr() << '\"' << std::endl;
}
funcC (foo);
funcCxx (foo);
C 函式指標樣式 ( funcC ) 有效,但 C std::function ( funcCxx ) 無效。
我得到這個編譯器錯誤candidate template ignored: could not match 'function<type-parameter-0-0 ()>' against 'double (*)()'
知道是什么導致了這個錯誤嗎?以防萬一,這是用 C 17 在 clang 中編譯的,但我認為這不是編譯器錯誤。
uj5u.com熱心網友回復:
無法推斷它,因為您沒有傳遞 a std::functionto funcCxx。
模板實參推導中,函式實參和形參型別必須匹配。否則扣減失敗。
您可以讓函式采用任何型別,而不是將其限制為函式指標,或者std::function然后您可以構造std::function函式內部:
template <typename V>
void funcCxx (V&& v){
auto f = std::function(std::forward<V>(v));
std::cout << "C function's value is\"" << f() << '\"' << std::endl;
}
uj5u.com熱心網友回復:
另一個答案很好地解釋了為什么你不能使用函式模板std::function從函式指標中推斷出來。但是在您的評論中,您說您的目標是限制模板引數,只允許可以不帶引數呼叫的型別。
在 c 20 中,引入了一些概念以使約束模板引數更容易。您可以使用該invocable概念僅允許可呼叫的型別。如果invocable沒有引數,它只接受可以不帶引數呼叫的型別:
void funcCxx20(std::invocable auto fptr) {
std::cout << "C 20 function's value is\"" << fptr() << '\"' << std::endl;
}
在 c 17 中,您可以使用std::is_invocablewithstd::enable_if_t來完成同樣的事情:
template <typename F>
std::enable_if_t<std::is_invocable_v<F>, void> funcCxx(F&& fptr) {
std::cout << "C function's value is\"" << fptr() << '\"' << std::endl;
}
在 c 14 中,可以使用舊形式的enable_if和這個解決方案
在這兩種情況下,您都可以using V = decltype(fptr())在函式內部添加以推斷回傳值型別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/420592.html
標籤:
上一篇:cpp中的介面
