如何在c++中编写使用其他函数的函数
How to write functions that use other functions in C++
考虑下面的代码,它包含在我制作的一个库中。
#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
}
注意两个函数有相同的签名。现在,我想写第三个函数不管它作用于besselJ
还是besselH1
都是一样的。我尝试了以下命令
template<std::complex<double> (*T)(int, std::complex<double>)>
std::complex<double> diffBessel(int order, std::complex<double> z)
{
return T(order-1, z)-T(order+1,z);
}
当一个成员函数试图使用语法diffbessel<besselJ>(int, std::complex<double>
时,GCC报错the value of 'besselJ' is not usable in a constant expression
。请参阅这个答案以获得解释。
是否有一种方法可以像上面的模板代码那样做,如果它不诉诸于在struct
s中包装besselJ
和besselH1
?我认为结构体会增加不必要的复杂性。
更新:这工作得很漂亮,正如@aschepler建议的那样。实际代码中存在名称冲突。我多看了1001次才发现。我对其他StackOverflow文章感到困惑,这些文章建议这不会工作,因为函数指针是可变的。
前提:
如果besselJ
在你的例子中是函数的名字,而不是你用作模板参数的变量的名字,那么传递一个函数指针作为非类型模板参数应该工作。查看实例
替代解决方案:
如果函数指针保存在运行时计算其值的变量中,则不允许将该函数指针用作模板实参。如果想使用运行时函数指针,可以使用常规的函数参数,而不是模板参数:
#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);
}
更习惯的解决方案:(需要c++ 11)
如果你想要更多的灵活性,c++ 11可以使用std::function<>
:
#include <complex>
#include <functional>
std::complex<double> diffBessel(
std::function<std::complex<double>(int, std::complex<double>)> fxn,
int order,
std::complex<double> z
)
{
return fxn(order-1, z)- fxn(order+1,z);
}
在这两种情况下,您的函数都可以这样调用:
int main()
{
std::complex<double> c;
/* ... */
diffBessel(besselH1, 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);
}
同样,您将以与调用以前版本完全相同的方式调用它。
模板需要在编译时知道它们的参数。在运行时将模板参数从变量中取出是行不通的。
让函数指针成为函数形参。它不需要是模板函数。
std::complex<double> diffBessel(int order,
std::complex<double> z,
std::complex<double> (*T)(int, std::complex<double>))
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- 保留对其他类的成员函数的引用
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 如何在其他文件中使用函数
- C++变量名(可以将 main 声明为变量,但对于其他函数名称则不然)
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- 为什么 memcpy() 和其他类似的函数使用汇编?
- 为什么 c++ 中的 main() 函数不采用除 int 和 void 之外的任何其他返回类型
- 泛型枚举和其他类型的重载模板函数
- error dllimport 函数的定义不允许在一个特定的联合中,而其他类、结构和联合将按预期导出
- 将基类的成员函数重载到其他派生类C++
- 如何在其他类中使用参数化构造函数制作类的对象?
- 为什么 ADL 的运算符函数行为与其他函数不同?
- 没有头文件如何使用c ++调用其他模块中的函数?
- 在C++单元测试上下文中,抽象基类是否应将其他抽象基类作为函数参数
- 如何制作 cmakelists.txt编译使用在其他地方声明和实现的函数和类的 CPP
- 成员函数不能为集合迭代器和const_iterator的输入重载(但可以为其他 STL 迭代器重载)
- 通过向构造函数其他对象引用页面来创建对象