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

C++ 如何为相同的模板参数类型专门化/重载函数?,c++,templates,casting,overloading,c++17,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<>

考虑以下代码:

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

不,您不能这样做,因为这将是对函数进行部分专门化的尝试,这是不允许的。相反,您必须使用一个中间模板类,而不是专门化的模板类


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

不,您不能这样做,因为这将是试图部分专门化函数,这是不允许的。相反,您必须使用一个中间模板类,而不是专门化的模板类


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

您不能部分专门化函数,并且您的重载将是不明确的

您可以添加可以部分专门化的类:

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); }
};
模板结构castinpl;
模板结构castinpl
{
T运算符()(T)常量{return T;}
};
模板结构castinpl
{
__m256d运算符()(uuum256i t)常量{return mm256_castsi256_pd(t);}
};
模板结构castinpl
{
__m256i运算符()(uuum256d t)常量{return mm256_castpd_si256(t)}
};
然后

class Helper {
public:
    template<typename taResult, typename taParam>
    static taResult Cast(const taParam par)
    { 
        return CastImpl<taResult, taParam>{}(par);
    }
};
类助手{
公众:
模板
静态taResult Cast(const taParam par)
{ 
返回castinpl{}(par);
}
};

您不能部分专门化函数,并且您的重载将是不明确的

您可以添加可以部分专门化的类:

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); }
};
模板结构castinpl;
模板结构castinpl
{
T运算符()(T)常量{return T;}
};
模板结构castinpl
{
__m256d运算符()(uuum256i t)常量{return mm256_castsi256_pd(t);}
};
模板结构castinpl
{
__m256i运算符()(uuum256d t)常量{return mm256_castpd_si256(t)}
};
然后

class Helper {
public:
    template<typename taResult, typename taParam>
    static taResult Cast(const taParam par)
    { 
        return CastImpl<taResult, taParam>{}(par);
    }
};
类助手{
公众:
模板
静态taResult Cast(const taParam par)
{ 
返回castinpl{}(par);
}
};

您可以使用helper类/结构模板来实现
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);
}
使用uu m256d=double;
使用_m256i=int;
模板结构RealHelper;
类助手
{
公众:
模板静态taResult Cast(const taParam par)
{
返回RealHelper::doit(par);
}
私人:
};
模板结构RealHelper
{
内联静态m256d doit(常数m256i par)
{
//返回值_mm256_castsi256_pd(par);
返回票面金额;
}
};
模板结构RealHelper
{
内联静态m256i doit(常数m256d par)
{
//返回mm256 castpd si256(par);
返回票面金额;
}
};
模板结构RealHelper
{
内联静态T doit(常数T par)
{
返回票面金额;
}
};
int main()
{
autov1=Helper::Cast(10);
autov2=Helper::Cast(20);
autov3=Helper::Cast(30);
自动v4=Helper::Cast(40);
}

您可以使用helper类/结构模板来实现
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);
}
使用uu m256d=double;
使用_m256i=int;
模板结构RealHelper;
类助手
{
公众:
模板静态taResult Cast(const taParam par)
{
返回RealHelper::doit(par);
}
私人:
};
模板结构RealHelper
{
内联静态m256d doit(常数m256i par)
{
//返回值_mm256_castsi256_pd(par);
返回票面金额;
}
};
模板结构RealHelper
{
内联静态m256i doit(常数m256d par)
{
//返回mm256 castpd si256(par);
返回票面金额;
}
};
模板结构RealHelper
{
内联静态T doit(常数T par)
{
返回票面金额;
}
};
int main()
{
autov1=Helper::Cast(10);
autov2=Helper::Cast(20);
autov3=Helper::Cast(30);
自动v4=Helper::Cast(40);
}
我想在助手中添加一个函数来处理参数和返回类型相等的类型转换

根据
std::is_same::value
的值,使用SFINAE启用/禁用
Cast()
版本怎么样

一个简化的例子

#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"
 }
#包括
#包括
结构辅助程序
{
模板
静态标准::启用\u如果\u t
铸造(攻丝常数和标准杆)
{std::cout
我想在助手中添加一个函数来处理参数和返回类型相等的类型转换

根据
std::is_same::value
的值,使用SFINAE启用/禁用
Cast()
版本怎么样

一个简化的例子

#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"
 }
#包括
#包括
结构辅助程序
{
模板
静态标准::启用\u如果\u t
铸造(攻丝常数和标准杆)

{std::你的代码在复制到这里时是否丢失了一些模板参数;你能验证它的正确性吗?@DanielH:OP使用了专门化。那么,为什么不在这里使用普通重载呢?你提供了3个重载:一个采用uuum256i,一个采用uuum256d,另一个采用普通模板,不管你的通用算法是什么。看起来像李在
\u m256d
\u m256i
中定义强制转换操作符可以解决这个问题,而不需要
帮助程序
类。没有采用这种方法有什么原因吗?@Jarod42是的,我明白了,我只是希望它需要说
帮助程序::强制转换
。看起来你的代码丢失了一些模板参数当复制到这里时,你能验证它是否正确吗?@DanielH:OP使用了专门化。那么,为什么不在这里使用普通重载呢?你提供了3个重载:一个使用uuuuM256i,一个使用uuuM256d,一个使用普通模板,不管你的通用算法是什么。看起来像是在
\uM256d
中定义了强制转换操作符__m256i
解决了这个问题,而不需要
Helper
类。没有采取这种方法有什么原因吗?@Jarod42是的,我明白了,我只是希望它需要说
Helper::Cast
。为什么不允许对函数进行部分专业化?@DanielH,因为它.OP完全专业化了他的函数,我“这是允许的。”丹尼