首页 > 解决方案 > 如何根据精度轻松模板化数学函数?

问题描述

假设我有两个已经预定义的数学函数:

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++

解决方案


多亏了 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,那么您可以专门化或重载foodoublefloat让这些专门化/重载调用正确的函数。


推荐阅读