[英]How to replace "float (*fSqrt)(float)" with "std::function<float(float) fSqrt>" in C++?
I have a function with signature:我有一个带签名的函数:
template<class Type> bool isPrime(const Type& n,float (*fSqrt)(float),bool debug = false)
which works fine.这工作正常。
But,但,
template<class Type> bool isPrime(const Type& n,std::function<float(float)> fSqrt,bool debug = false)
causes compile-error.导致编译错误。
How to replace float (*fSqrt)(float)
with std::function<float(float) fSqrt>
?如何用
std::function<float(float) fSqrt>
替换float (*fSqrt)(float)
?
Please note: My ultimate objective is std::function<float(Type)>
, where Type is templated.请注意:我的最终目标是
std::function<float(Type)>
,其中Type是模板化的。
Wandbox ( https://wandbox.org/ ) shows: Wandbox ( https://wandbox.org/ ) 显示:
prog.cc: In function 'int main()':
prog.cc:91:28: error: no matching function for call to 'isPrime(int&, <unresolved overloaded function type>, bool)'
91 | std::cout<<(isPrime(n,std::sqrt,true)?"Positive":"Negative")<<'\n';
| ~~~~~~~^~~~~~~~~~~~~~~~~~
prog.cc:10:27: note: candidate: 'template<class Type> bool isPrime(const Type&, const float&, bool)'
10 | template<class Type> bool isPrime(const Type& n,const float& nSqrt = 0.0,bool debug = false) {
| ^~~~~~~
prog.cc:10:27: note: template argument deduction/substitution failed:
prog.cc:91:28: note: cannot convert 'std::sqrt' (type '<unresolved overloaded function type>') to type 'const float&'
91 | std::cout<<(isPrime(n,std::sqrt,true)?"Positive":"Negative")<<'\n';
| ~~~~~~~^~~~~~~~~~~~~~~~~~
prog.cc:81:27: note: candidate: 'template<class Type> bool isPrime(const Type&, std::function<float(float)>, bool)'
81 | template<class Type> bool isPrime(const Type& n,std::function<float(float)> fSqrt,bool debug = false) { // Type & std::function - compile-error
| ^~~~~~~
prog.cc:81:27: note: template argument deduction/substitution failed:
prog.cc:91:28: note: cannot convert 'std::sqrt' (type '<unresolved overloaded function type>') to type 'std::function<float(float)>'
91 | std::cout<<(isPrime(n,std::sqrt,true)?"Positive":"Negative")<<'\n';
| ~~~~~~~^~~~~~~~~~~~~~~~~~
OnlineGDB ( https://www.onlinegdb.com/# ) shows: OnlineGDB ( https://www.onlinegdb.com/# ) 显示:
main.cpp:91:38: error: no matching function for call to ‘isPrime(int&, , bool)’
std::cout<<(isPrime(n,std::sqrt,true)?"Positive":"Negative")<<'\n';
^
main.cpp:10:27: note: candidate: template bool isPrime(const Type&, const float&, bool)
template<class Type> bool isPrime(const Type& n,const float& nSqrt = 0.0,bool debug = false) {
^~~~~~~
main.cpp:10:27: note: template argument deduction/substitution failed:
main.cpp:91:38: note: cannot convert ‘sqrt’ (type ‘’) to type ‘const float&’
std::cout<<(isPrime(n,std::sqrt,true)?"Positive":"Negative")<<'\n';
^
main.cpp:81:27: note: candidate: template bool isPrime(const Type&, std::function, bool)
template<class Type> bool isPrime(const Type& n,std::function<float(float)> fSqrt,bool debug = false) { // Type & std::function - compile-error
^~~~~~~
main.cpp:81:27: note: template argument deduction/substitution failed:
main.cpp:91:38: note: cannot convert ‘sqrt’ (type ‘’) to type ‘std::function’
std::cout<<(isPrime(n,std::sqrt,true)?"Positive":"Negative")<<'\n';
^
Kindly help me out, please.请帮助我,请。
Thank you :)谢谢 :)
As others have pointed out std::sqrt
has multiple overload, and you should specify which one to deduce there to be a std:.function
.正如其他人指出的那样
std::sqrt
有多个重载,您应该指定哪一个来推断存在std:.function
。 For example static_cast<float(*)(float)>(std::sqrt)
.例如
static_cast<float(*)(float)>(std::sqrt)
。
However, you should not be taking the address of a standard library function.但是,您不应该获取标准库函数的地址。 See in detail here: Can I take the address of a function defined in standard library?
在此处详细查看: 我可以获取标准库中定义的函数的地址吗?
Secondly the std::function
comes with a type-erasure overhead .其次,
std::function
带有类型擦除开销。
Therefore, I suggest packing the std::sqrt
to a lambda, and use template argument to deduce the lambda by the compiler.因此,我建议将
std::sqrt
打包为 lambda,并使用模板参数由编译器推导出 lambda。 Something like就像是
template<class Type, typename Callable>
bool isPrime(const Type& n, Callable fSqrt, bool debug = false)
{
// ...
}
and call via并通过调用
isPrime(2.f, [](float val) { return std::sqrt(val); });
However, now isPrime
takes anything callable.但是,现在
isPrime
接受任何可调用的。 This can be restricted only for the specific one by sfinaeing the function.这可以通过 sfinaeing 功能仅针对特定的功能进行限制。
#include <type_traits> // std::enable_if, std::is_floating, std::invoke_result
template<class Type, typename Callable>
auto isPrime(const Type& n, Callable fSqrt, bool debug = false)
->std::enable_if_t<std::is_floating_point_v<std::invoke_result_t<Callable, Type>>, bool>
{
// ...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.