简体   繁体   English

如何专门化/重载相等模板参数类型的函数?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM