如何根据精度轻松模板化数学函数
How to easily templatize math functions based on precision?
假设我有两个已经预定义的数学函数:
float sqrtf(float a);
double sqrt(double a);
我有一些模板化代码,我正在编写C++我想在两者之间自动切换:
template<typename Precision>
void foo(Precision arg) {
sqrt<Precision>(arg); // Call into sqrtf or sqrt depending on type?
}
有没有一种简单的方法来完成上述工作,而不必手动重写所有重载?
为清楚起见进行编辑:这些是 C 和 CUDA 函数(例如。BLAS(,没有预构建的重载。
多亏了 C++17 的if constexpr
它就像
template <typename...>
struct always_false { static constexpr bool value = false; }; // used to make the static_asset value a dependent value otherwise it always fires
template<typename Precision>
void foo(Precision arg) {
if constexpr (std::is_same_v<Precision, double>)
sqrt(arg);
else if constexpr (std::is_same_v<Precision, float>)
sqrtf(arg);
else
static_assert(always_false<Precision>::value, "foo can only be called with the types double or float");
}
如果您不能使用 C++17,则可以针对double
和float
专用化或重载foo
,并让这些专用化/重载调用正确的函数。
我想你正在使用C函数。如果您改用 C++ 函数(C++有重载(,则无需玩任何技巧:
template<typename Precision>
void foo(Precision arg) {
std::sqrt(arg); // Calls the right overload depending on type of arg
}
所以痛点是我实际上需要支持 4 种类型:浮点数, 双人间、complex_float、complex_double
如果你必须使用 c 函数,那么你可以编写一个包装器。编写一个与正确的 C 函数不同的sqrt
:
template <typename T>
T my_sqrt(T x);
template<>
float my_sqrt(float x) { return sqrtf(x); }
以及其他三种类型的类似专业。然后在foo
只需调用该包装器
template<typename Precision>
void foo(Precision arg) {
my_sqrt(arg);
}
在 C++17 之前,您可以编写调用相应函数的模板专用化:
template<class NumericType>
typename std::enable_if<std::is_same<NumericType, double>::value, void>::type foo(const NumericType number) {
return sqrt(number);
}
以及您需要的类似重载。
相关文章:
- "error: no matching function for call to"构造函数错误
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 使用根/C++时出错:没有匹配的构造函数来初始化'TTree'
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- 超过了三次函数根平分搜索时间限制
- "virtual"对C++析构函数有何影响?
- C++ 友元函数在内存位置上有何不同?
- 指向成员函数的指针与指向数据成员的指针有何不同
- 使用函数的 CERN 根 5.34 错误消息
- 双重列表复制构造函数:与单一列表复制构造函数有何不同
- 找到函数的根但不是渐近的根
- 使用C++中的割线函数查找根
- C++03 12.4/12对通过指针显式调用基类析构函数有何说明
- C++正在查找函数的根
- 为什么 vsperfmon 告诉我被调用函数的包含时间比根函数的包含时间更长?
- 缺少复制构造函数与对象切片有何关系
- 递归函数插入二叉搜索树无法按根访问节点
- 基例如何影响使用递归函数的哪些行
- 使用布伦特算法找到函数 f 的根,带有初始猜测,但没有区间 [a,b] s.t. f(a)f(b)<0
- 如何在聚合根类中编写只读访问器函数