将C ++整数类型模板参数转换为“较长”整数类型

时间:2019-01-29 05:16:58

标签: c++ templates types

我有一个模板函数,该函数接受整数类型并对两个输入参数执行数学运算:

template<typename T, typename R>
R multiply( const T& lhs, const T& rhs ) {
  R ans = static_cast<R>( lhs ) * static_cast<R>( rhs );
  return ans;
}

(为简单起见,假设类型T和R始终是无符号整数类型,或者我进行了适当的检查以确保。)

在这个人为的示例中,您可以看到我正在做一个简单的乘法(仅用于说明)。这个想法是要传递一个类型R,它是类型T的两倍多;这将使整个产品适合返回值:

uint64_t Product64 = multiply<uint32_t,uint64_t>( 0xFFFFFFFF, 0xFFFFFFFF );
uint16_t Product16 = multiply<uint8_t,uint16_t>( 0xFF, 0xFF );

我想知道是否有任何方法来省去第二个模板参数,并自动计算出一种[至少],在编译时的宽度为T型的两倍。

注意:仅在R上始终使用最大可用整数类型(uint64_t)并不是我的解决方案。理想情况下,我希望编译时计算的类型足够大,以容纳两倍于T类型的位(例如,当T = uint8_t,R = uint16_t时)。

在我看来,使用limit或type_traits或类似的东西应该可以实现,但是到目前为止我还没有想到解决方案。 C ++ 11或更高版本是可以的。我宁愿避免使用Boost,但是如果那是唯一的方法,那么我也希望看到基于Boost的解决方案。

1 个答案:

答案 0 :(得分:5)

您可以创建自己的模板大小类型,并使用它们来定义返回类型,如下所示:

#include <cstdint>
template<int N>
struct sized_uint {};
template<> struct sized_uint<8 > { using type=std::uint8_t; };
template<> struct sized_uint<16> { using type=std::uint16_t; };
template<> struct sized_uint<32> { using type=std::uint32_t; };
template<> struct sized_uint<64> { using type=std::uint64_t; };

#include <climits>
template<typename T>
auto multiply(T lhs, T rhs)
{
  using R=typename sized_uint<CHAR_BIT*sizeof(T)*2>::type;
  return static_cast<R>(static_cast<R>(lhs) * static_cast<R>(rhs));
}

See it live.