我正在编写使用三角函数的科学计算代码,并且由于我不仅需要使用 float / double ,还需要使用多精度 float ,所以我正在对函数和类进行模板化。
假设我只是编写一个函数来计算 sin(pi*x) * cos(pi*x)
:
template <class Real>
Real sincos(const Real& x);
如何使用正确版本的三角函数和 pi 值?多精度浮点库通常有自己的三角函数版本,并且仅为 float
、double
和 定义了
,而 std::
版本>long doubleM_PI
甚至不是标准的。
我尝试将函数指针作为参数,但是 std::
版本是重载函数而不是模板,所以我应该把它放在 (double (*)(double)&std::sin )
这会损害可读性并且很难使用。
template <class Real>
Real sincos(const Real& x,
Real (*sin)(const Real&), Real (*cos)(const Real&), const Real& pi)
{
return sin(pi*x) * cos(pi*x);
}
// I don't think it's well designed function if it's hard to use like this.
double s = sincos<double>(0, (double (*)(double))&std::sin,
(double (*)(double))&std::cos,
M_PI);
my_mpf = sincos<my_mpf>(0, somewhere::my_sin, somewhere::my_cos, my_mpf_version_of_pi);
问题是需要很多数学函数,所以我不能简单地将它们放入函数参数中。
我应该如何概括这些计算?
最佳答案
您可以考虑使用 char_traits
路线。
// default implementation calls std::<stuff>
template<class T>
struct trig_traits {
static constexpr T pi() { return T(3.14159265359); }
static auto sin(T v) { return std::sin(v); }
static auto cos(T v) { return std::cos(v); }
// etc.
};
然后您可以专注于 trig_traits<my_mpf>
如所须。您的实际函数模板将如下所示
template <class Real>
Real sincos(const Real& x) {
using traits = trig_traits<Real>;
return traits::sin(traits::pi() * x) * traits::cos(traits::pi() * x);
}
关于c++ - 如何将三角函数用于模板函数/类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30365684/