确定“最优”模板参数包中的常见数字类型 [英] Determining the "optimal" common numeric type in a template parameter pack

查看:95
本文介绍了确定“最优”模板参数包中的常见数字类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在模板参数包中确定常见数字类型的最佳方法是:

What is the best way to determine a common numeric type in a template parameter pack with:



  1. 在将参数包中的任何类型转换为理想状态时,

  2. 没有上溢/下溢的风险common type?

可变参数模板( best_common_numeric_type 因此:

template<typename... NumericTypes>
auto some_numeric_func(const NumericTypes&...)
-> typename best_common_numeric_type<NumericTypes...>::type;

并具有如下实例化:

[1] best_common_numeric_type<long, unsigned long, float, double, int>::type = double
[2] best_common_numeric_type<unsigned int, unsigned long>::type = unsigned long
[3] best_common_numeric_type<signed int, signed long>::type = signed long
[4] best_common_numeric_type<signed int, unsigned int>::type = signed long
[5] best_common_numeric_type<signed int, unsigned long>::type = int128_t (maybe)

4]例如, :: type 必须 signed long ,因为 signed int 无法保存 unsigned int ,没有溢出的风险,反之 unsigned int

So in case [4] for example, ::type would have to be signed long, since signed int could not hold an unsigned int without risk of overflow, and conversely unsigned int could not hold a signed int without risk of underflow.

这同样适用于[5],除了现在签署int c $ c> signed long 不再足够,因为它无法保存 unsigned long ,没有溢出的风险。

The same applies in [5], except now a signed long is no longer sufficient since it could not hold the unsigned long without risk of overflow.

(实现可能是数据模型

那么,什么可能是C ++ 11中最好的方法来实现呢?

So what might be the best way in C++11 to achieve this?

推荐答案

我有点迟到了,
这里是我没有Boost的解决方案:

I am a little bit late to the party, here is my solution without Boost:

#include <type_traits>
#include <cstdint>
  
template<class I, bool Signed> struct mk_signed { typedef I       type; };
template<>   struct mk_signed<uint8_t , true>   { typedef int16_t type; };
template<>   struct mk_signed<uint16_t, true>   { typedef int32_t type; };
template<>   struct mk_signed<uint32_t, true>   { typedef int64_t type; };
template<>   struct mk_signed<uint64_t, true>   { typedef int64_t type; }; 
  
template <typename... Ts> struct best_common_numeric_type;
template <typename T>     struct best_common_numeric_type<T> { typedef T type; };
  
template <typename T, typename... Ts>
struct best_common_numeric_type<T, Ts...> {
   typedef typename best_common_numeric_type<Ts...>::type TS;     
   typedef typename std::conditional < (sizeof(T) > sizeof(TS)), T, TS>::type  bigger_integral;
   constexpr static bool fp = std::is_floating_point<T>::value || std::is_floating_point<TS>::value;
   constexpr static bool have_signed = !fp && (std::is_signed<T>::value || std::is_signed<TS>::value);
  
   typedef typename std::conditional <
     fp,
     typename std::common_type<T,TS>::type,
     typename mk_signed<bigger_integral,have_signed>::type
   >::type type;
};

这篇关于确定“最优”模板参数包中的常见数字类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆