如何添加void/null作为默认参数的函数/lambda指针,在c++ ?



现在签名

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的数据类型,否则不可能有默认参数,例如,编译器不能从无到有地推导出类型。

相关内容

  • 没有找到相关文章

最新更新