4

我有一个模板化的数学函数,它接受两个值,对它们进行一些数学运算,然后返回一个相同类型的值。

template <typename T>
T math_function(T a, T b) {
  LongT x = MATH_OP1(a,b);
  return MATH_OP2(x,a);
}

我想将中间值(在 x 中)存储在一个基本上是 T 的长版本(上面称为 LongT)的类型中。所以,如果 T 是浮点数,我希望 x 是双精度数;如果 T 是一个 int,我希望 x 是一个 long int。

有没有办法做到这一点?我试过enable_if了,但似乎我真的需要一个enable_if_else.

我宁愿让编译器自己弄清楚 LongT 使用什么。我宁愿在调用函数时不必指定它。

4

5 回答 5

5

您可以定义将产生所需类型的类型映射:

template <typename T> struct long_type;
template <> struct long_type<int> {
   typedef long type;
};
template <> struct long_type<float> {
   typedef double type;
};

然后使用该元功能:

template <typename T>
T math_function(T a, T b) {
  typename long_type<T>::type x = MATH_OP1(a,b);
  return static_cast<T>(MATH_OP2(x,a));
}

使用此特定实现,您的模板将无法针对您提供特征的类型以外的任何类型进行编译long_type。您可能希望提供一个仅映射到自身的通用版本,这样如果输入就是long long int所使用的(假设您的体系结构中没有更大的类型)。

于 2012-08-08T21:56:24.743 回答
5

例如,假设您不需要处理,只需为andT=long创建特征:intfloat

template <typename T>
struct LongT;

template <>
struct LongT<int>
{
    typedef long value_type;
};

template <>
struct LongT<float>
{
    typedef double value_type;
};

template <typename T>
T math_function(T a, T b) {
  typename LongT<T>::value_type x = MATH_OP1(a,b);
  return MATH_OP2(x,a);
}
于 2012-08-08T21:56:34.507 回答
3

在 C++11 中,您可以使用auto关键字来检索MATH_OP. 它是安全的并由编译器处理。

auto x = MATH_OP1(a,b);
于 2012-08-08T22:13:46.397 回答
1
template<typename T> struct LongT  {typedef T type;}

template<> struct LongT<int8_t>    {typedef int16_t type;}
template<> struct LongT<int16_t>   {typedef int32_t type;}
template<> struct LongT<int32_t>   {typedef int64_t type;}
template<> struct LongT<int64_t>   {typedef intmax_t type;}
// same for unsigned ...

template<> struct LongT<float>     {typedef double type;}
// template<> struct LongT<double> {typedef long double type;}

像这样使用:

typename LongT<T>::type  x;
于 2012-08-09T12:55:42.053 回答
0

您可以编写自己的结构的专业化,或使用类似的东西

#include <type_traits>

template<typename T>
void func(const T& f, const T& s)
{
   typename std::conditional
   <
      std::is_same<T, float>::value,
      double,
      typename std::conditional
      <
        std::is_same<T, int>::value,
        long,
        void
      >::type
   >::type X(f + s);
   (void)X;
}

int main()
{
   func(1, 1);
   func(1.0f, 1.0f);
   func(1.0, 1.0);
}

http://liveworkspace.org/code/8f75236b880a3fe210a8751e485a47ed

但是写你自己的专业,因为大卫或马克很聪明。

于 2012-08-08T22:03:00.030 回答