C++ 如何在C+中编写使用其他函数的函数+;
考虑下面的代码,它包含在我创建的库中C++ 如何在C+中编写使用其他函数的函数+;,c++,templates,function-pointers,C++,Templates,Function Pointers,考虑下面的代码,它包含在我创建的库中 #include <complex> std::complex<double> besselJ(int order, std::complex<double> z) { // Function call } std::complex<double> besselH1(int order, std::complex<double> z) { // Function call } 当
#include <complex>
std::complex<double> besselJ(int order, std::complex<double> z)
{
// Function call
}
std::complex<double> besselH1(int order, std::complex<double> z)
{
// Function call
}
当成员函数尝试使用语法diffbessel(int,std::complex
)时,GCC抱怨常量表达式中的'besselJ'值不可用。有关说明,请参阅
如果上面的模板化代码不需要在struct
s中包装besselJ
和besselH1
,那么有没有一种方法可以做类似的事情呢?我认为struct会增加不必要的复杂性
更新:正如@aschepler所建议的那样,这很好地工作。实际代码中存在名称冲突。这需要额外的1001次查看。我被其他StackOverflow文章弄糊涂了,这些文章认为这不起作用,因为函数指针是可变的。模板需要在编译时知道它们的参数在运行时从变量中拉出模板参数将不起作用
只需将函数指针设置为函数参数,它不需要是模板函数
std::complex<double> diffBessel(int order,
std::complex<double> z,
std::complex<double> (*T)(int, std::complex<double>))
std::复杂diffBessel(int顺序,
std::复数z,
std::complex(*T)(int,std::complex))
模板需要在编译时知道其参数。在运行时将模板参数从变量中拉出将不起作用
只需将函数指针设置为函数参数,它不需要是模板函数
std::complex<double> diffBessel(int order,
std::complex<double> z,
std::complex<double> (*T)(int, std::complex<double>))
std::复杂diffBessel(int顺序,
std::复数z,
std::complex(*T)(int,std::complex))
前提:
如果示例中的besselJ
是函数的名称,而不是用作模板参数的变量的名称,那么将函数指针作为非类型模板参数传递应该是有效的
见a
替代解决方案:
如果函数指针保存在运行时计算其值的变量中,则不允许将该函数指针用作模板参数。如果要使用运行时函数指针,可以使用常规函数参数而不是模板参数:
#include <complex>
std::complex<double> diffBessel(
std::complex<double> (*fxn)(int, std::complex<double>),
int order,
std::complex<double> z
)
{
return fxn(order-1, z) - fxn(order+1,z);
}
#包括
复杂漫射(
std::complex(*fxn)(int,std::complex),
整数阶,
std::复数z
)
{
返回fxn(订单-1,z)-fxn(订单+1,z);
}
更惯用的解决方案:(需要C++11)
如果您想要更大的灵活性,使用C++11可以使用std::function
:
#包括
#包括
复杂漫射(
函数fxn,
整数阶,
std::复数z
)
{
返回fxn(订单-1,z)-fxn(订单+1,z);
}
在这两种情况下,您的函数都可以通过以下方式调用:
int main()
{
std::complex<double> c;
/* ... */
diffBessel(besselH1, 2, c);
}
intmain()
{
std::复合物c;
/* ... */
diffBessel(bessel1,2,c);
}
进一步的可能性:
作为进一步的可能性,如果您不想要或不能使用std::function
,您可以通过将其设置为模板,让函数接受任何可调用对象:
template<typename F>
std::complex<double> diffBessel(
F f,
int order,
std::complex<double> z
)
{
return f(order-1, z) - f(order+1,z);
}
模板
复杂漫射(
F,,
整数阶,
std::复数z
)
{
返回f(订单-1,z)-f(订单+1,z);
}
同样,调用此函数的方式与调用以前版本的方式完全相同。前提:
如果示例中的besselJ
是函数的名称,而不是用作模板参数的变量的名称,那么将函数指针作为非类型模板参数传递应该是有效的
见a
替代解决方案:
如果函数指针保存在运行时计算其值的变量中,则不允许将该函数指针用作模板参数。如果要使用运行时函数指针,可以使用常规函数参数而不是模板参数:
#include <complex>
std::complex<double> diffBessel(
std::complex<double> (*fxn)(int, std::complex<double>),
int order,
std::complex<double> z
)
{
return fxn(order-1, z) - fxn(order+1,z);
}
#包括
复杂漫射(
std::complex(*fxn)(int,std::complex),
整数阶,
std::复数z
)
{
返回fxn(订单-1,z)-fxn(订单+1,z);
}
更惯用的解决方案:(需要C++11)
如果您想要更大的灵活性,使用C++11可以使用std::function
:
#包括
#包括
复杂漫射(
函数fxn,
整数阶,
std::复数z
)
{
返回fxn(订单-1,z)-fxn(订单+1,z);
}
在这两种情况下,您的函数都可以通过以下方式调用:
int main()
{
std::complex<double> c;
/* ... */
diffBessel(besselH1, 2, c);
}
intmain()
{
std::复合物c;
/* ... */
diffBessel(bessel1,2,c);
}
进一步的可能性:
作为进一步的可能性,如果您不想要或不能使用std::function
,您可以通过将其设置为模板,让函数接受任何可调用对象:
template<typename F>
std::complex<double> diffBessel(
F f,
int order,
std::complex<double> z
)
{
return f(order-1, z) - f(order+1,z);
}
模板
复杂漫射(
F,,
整数阶,
std::复数z
)
{
返回f(订单-1,z)-f(订单+1,z);
}
同样,调用此函数的方式与调用以前版本的方式完全相同。链接的答案没有解释为什么diffbessel(args)
不起作用。据我所知,它应该起作用。你能显示GCC投诉的确切代码吗?感谢你们两位。它确实起作用。我忽略了一个愚蠢的错误,尽管我看了几个小时的代码。链接答案的可能重复无法解释为什么diffbessel(args)
不起作用。据我所知,它应该起作用。你能显示GCC抱怨的确切代码吗?感谢你们两位。它确实起作用。我忽略了一个愚蠢的错误,尽管我看了几个小时的代码。确实可能是重复的,但这失败了,因为我有另一个函数使用基本函数diffBessel
。我需要一个数量可变的函数指针,而这充其量是非常不雅观的