[英]How to specialize/overload a function for equal template parameter types?
Consider the following code: 考虑以下代码:
class Helper {
public:
template<typename taResult, typename taParam> static taResult Cast(const taParam par);
};
template<> inline __m256d Helper ::Cast(const __m256i par) {
return _mm256_castsi256_pd(par);
}
template<> inline __m256i Helper ::Cast(const __m256d par) {
return _mm256_castpd_si256(par);
}
I want to add to the Helper
a function to handle casts where the parameter and the return types are equals. 我想向
Helper
添加一个函数来处理参数与返回类型相等的类型转换。 All my attempts to specialize/overload so far have failed with different compilation errors. 到目前为止,我所有尝试进行专门化/重载的尝试均因不同的编译错误而失败。
Something like the following in the class body: 类主体中的内容如下:
template<typename T> static T Cast(const T par) {
return par;
}
You cannot partial specialize function, and your overload would be ambiguous. 您不能局部化特殊功能,并且您的重载将是模棱两可的。
You can add class which you can partial specialize though: 您可以添加可以部分专业化的类:
template <typename To, typename From> struct CastImpl;
template <typename T> struct CastImpl<T, T>
{
T operator()(T t) const { return t; }
};
template <> struct CastImpl<__m256d, __m256i>
{
__m256d operator()(__m256i t) const { return _mm256_castsi256_pd(t); }
};
template <> struct CastImpl<__m256i, __m256d>
{
__m256i operator()(__m256d t) const { return _mm256_castpd_si256(t); }
};
and then 接着
class Helper {
public:
template<typename taResult, typename taParam>
static taResult Cast(const taParam par)
{
return CastImpl<taResult, taParam>{}(par);
}
};
No you can not, because that would be an attempt to partially specialize a function, which is not allowed. 不,您不能,因为这是对部分功能进行专业化的尝试,这是不允许的。 Instead, you'd have to use an intermediate template class, which than can be specialized.
取而代之的是,您必须使用一个中间模板类,该模板类可以专门化。
I can provide example if needed. 如果需要,我可以提供示例。
You can use a helper class/struct template to implement Helper::Cast
. 您可以使用帮助程序类/结构模板来实现
Helper::Cast
。
Here's a simple program that has uses a few shortcuts to demonstrate the concept. 这是一个简单的程序,它使用一些快捷方式来演示该概念。
using __m256d = double;
using __m256i = int;
template<typename taResult, typename taParam> struct RealHelper;
class Helper
{
public:
template<typename taResult, typename taParam> static taResult Cast(const taParam par)
{
return RealHelper<taResult, taParam>::doit(par);
}
private:
};
template <> struct RealHelper<__m256d, __m256i>
{
inline static __m256d doit(const __m256i par)
{
// return _mm256_castsi256_pd(par);
return par;
}
};
template <> struct RealHelper<__m256i, __m256d>
{
inline static __m256i doit(const __m256d par)
{
// return _mm256_castpd_si256(par);
return par;
}
};
template <typename T> struct RealHelper<T, T>
{
inline static T doit(const T par)
{
return par;
}
};
int main()
{
auto v1 = Helper::Cast<int, double>(10);
auto v2 = Helper::Cast<double, int>(20);
auto v3 = Helper::Cast<int, int>(30);
auto v4 = Helper::Cast<double, double>(40);
}
I want to add to the Helper a function to handle casts where the parameter and the return types are equals.
我想向助手添加一个函数来处理参数与返回类型相等的类型转换。
What about using SFINAE to enable/disable a Cast()
version according the value of std::is_same<taResult, taParam>::value
? 如何使用SFINAE根据
std::is_same<taResult, taParam>::value
启用/禁用Cast()
版本?
A simplified example 简化的例子
#include <iostream>
#include <type_traits>
struct Helper
{
template <typename taR, typename taP>
static std::enable_if_t<false == std::is_same<taR, taP>::value, taR>
Cast (taP const & par)
{ std::cout << "different Cast" << std::endl; return {}; }
template <typename taR, typename taP>
static std::enable_if_t<true == std::is_same<taR, taP>::value, taR>
Cast (taP const & par)
{ std::cout << "equal Cast" << std::endl; return par; }
};
template <>
int Helper::Cast<int, long> (long const & par)
{ std::cout << "int/long Cast" << std::endl; return {}; }
template <>
long Helper::Cast<long, int> (int const & par)
{ std::cout << "long/int Cast" << std::endl; return {}; }
int main()
{
Helper::template Cast<int>(0); // print "equal Cast"
Helper::template Cast<int>(0L); // print "int/log Cast"
Helper::template Cast<long>(0); // print "long/int Cast"
Helper::template Cast<long>("foo"); // print "different Cast"
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.