现在签名
template<class TypeData,typename TypeFunc>
bool isPrime(const TypeData& n,TypeFunc fSqrt,bool debug = false)
,这与
非常匹配std::cout<<(isPrime(n,fSqrt)?"Positive":"Negative")<<'n';
But, myintensity比如
template<class TypeData,typename TypeFunc>
bool isPrime(const TypeData& n,TypeFunc fSqrt = nullptr,bool debug = false)
或
template<class TypeData,typename TypeFunc>
bool isPrime(const TypeData& n,TypeFunc fSqrt = NULL,bool debug = false)
被
调用std::cout<<(isPrime(n)?"Positive":"Negative")<<'n';
由于函数内部有一个静态变量,所以不能重载。对于这个函数模板,只有不同的
class TypeData
应该给出不同的模板函数。
请告诉我正确的语法。如果c++不支持这个,我可以使用什么替代方法?
编译错误
forTypeFunc fSqrt = nullptr
main.cpp:90:23: error: no matching function for call to ‘isPrime(int&)’
std::cout<<(isPrime(n)?"Positive":"Negative")<<'n';
^
main.cpp:9:49: note: candidate: template bool isPrime(const TypeDate&, TypeFunc, bool)
template<class TypeDate,typename TypeFunc> bool isPrime(const TypeDate& n,TypeFunc fSqrt = nullptr,bool debug = false) {
^~~~~~~
main.cpp:9:49: note: template argument deduction/substitution failed:
main.cpp:90:23: note: couldn't deduce template parameter ‘TypeFunc’
std::cout<<(isPrime(n)?"Positive":"Negative")<<'n';
^
forTypeFunc fSqrt = NULL
main.cpp:90:23: error: no matching function for call to ‘isPrime(int&)’
std::cout<<(isPrime(n)?"Positive":"Negative")<<'n';
^
main.cpp:9:49: note: candidate: template bool isPrime(const TypeDate&, TypeFunc, bool)
template<class TypeDate,typename TypeFunc> bool isPrime(const TypeDate& n,TypeFunc fSqrt = NULL,bool debug = false) {
^~~~~~~
main.cpp:9:49: note: template argument deduction/substitution failed:
main.cpp:90:23: note: couldn't deduce template parameter ‘TypeFunc’
std::cout<<(isPrime(n)?"Positive":"Negative")<<'n';
^
它们基本上是一样的。
可以使用std::identity
作为默认的TypeFunc
类型
#include <functional>
template<class TypeData,typename TypeFunc = std::identity>
bool isPrime(const TypeData& n,TypeFunc fSqrt = {}, bool debug = false) {
if constexpr (std::is_same_v<TypeFunc, std::identity>) return false;
else {
// ...
}
}
演示。
如果你的编译器不支持c++ 20,你可以简单地定义你自己的std::identity
:
struct Identity {
template<class T>
constexpr decltype(auto) operator()(T&& t) const noexcept {
return std::forward<T>(t);
}
};
重载实际上是一个选项,你可以让一个重载调用另一个:
template<class TypeData, typename TypeFunc>
bool isPrime(const TypeData& n, TypeFunc fSqrt, bool debug = false);
template<class TypeData>
bool isPrime(const TypeData& n, bool debug = false)
{
using std::sqrt;
if constexpr (std::is_integral_v<TypeData>)
{
return isPrime(n, static_cast<double(*)(double)>(sqrt), debug);
}
else if constexpr (std::is_floating_point_v<TypeData>)
{
return isPrime(n, static_cast<TypeData(*)(TypeData)>(sqrt), debug);
}
else
{
// this covers e.g. std::complex
return isPrime(n, static_cast<TypeData(*)(TypeData const&)>(sqrt), debug);
// for any other type we assume the overload accepts by
// const reference as well (if there's one at all...)
// if not, we still can fall back to the other overload
}
}
此解决方案立即选择一个合适的平方根函数,如果函数参数默认为nullptr
,则无论如何都必须解决此问题。
您可以使用带有正确原型的默认初始化std::function
:
template<class TypeData>
bool isPrime(const TypeData& n,std::function<const decltype(n)&(const decltype(n)&)> fSqrt={},bool debug = false)
您可以检查函数是否有效,或者通过简单的if (fSqrt)
检查函数是否为默认函数完整示例:https://godbolt.org/z/zfMazebso
原型必须只依赖于n
的数据类型,否则不可能有默认参数,例如,编译器不能从无到有地推导出类型。