假设我有两个已经预定义的数学函数:
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),它们没有预先构建的重载。
发布于 2019-02-08 04:03:18
多亏了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,并让这些专门化/重载调用正确的函数。
发布于 2019-02-08 04:04:38
我想您使用的是C functions。如果你使用C++ functions (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);
}发布于 2019-02-08 04:05:59
在使用C++17之前,您可以编写调用适当函数的模板专门化:
template<class NumericType>
typename std::enable_if<std::is_same<NumericType, double>::value, void>::type foo(const NumericType number) {
return sqrt(number);
}和你需要的类似的重载。
https://stackoverflow.com/questions/54581350
复制相似问题