确定“最优”模板参数包中的常见数字类型 [英] Determining the "optimal" common numeric type in a template parameter pack
问题描述
在模板参数包中确定常见数字类型的最佳方法是:
What is the best way to determine a common numeric type in a template parameter pack with:
- 在将参数包中的任何类型转换为理想状态时,
- 没有上溢/下溢的风险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屋!