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

时间:2017-08-08 20:01:25

标签: c++ templates casting overloading c++17

请考虑以下代码:

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);
}

我想在Helper函数中添加一个函数来处理参数和返回类型等于的强制转换。到目前为止,我所有的特化/重载尝试都因编译错误而失败。

类体中的以下内容:

template<typename T> static T Cast(const T par) {
  return par;
}

4 个答案:

答案 0 :(得分:3)

你不能部分专门化功能,你的重载也会模棱两可。

您可以添加可以部分专业化的课程:

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); }
};

然后

class Helper {
public:
    template<typename taResult, typename taParam>
    static taResult Cast(const taParam par)
    { 
        return CastImpl<taResult, taParam>{}(par);
    }
};

答案 1 :(得分:1)

不,你不能,因为那是尝试部分专门化一个功能,这是不允许的。相反,你必须使用一个中间模板类,而不是专门的。

如果需要,我可以提供示例。

答案 2 :(得分:1)

您可以使用帮助器类/结构模板来实现Helper::Cast

这是一个简单的程序,它使用了一些快捷方式来演示这个概念。

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);
}

答案 3 :(得分:0)

  

我想向Helper添加一个函数来处理参数和返回类型相等的转换。

如何根据Cast()的值使用SFINAE启用/禁用std::is_same<taResult, taParam>::value版本?

简化示例

#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"
 }