如何自动匹配整数类型的双倍宽度类型,简化模乘模板函数调用?
问题
有时我需要使用双倍宽度类型进行中间计算,比如下面这个返回两数模m乘积的函数:
template <typename T, typename DT> T multiply(T x, T y, T mod) { return (static_cast<DT>(x % mod) * (y % mod)) % mod; }
当mod值接近类型T的最大值时,这种转换是必须的。但调用时必须传入两个模板参数:
z = multiply<int32_t, int64_t>(x, y, m)
这种写法既不美观又容易出错,有没有办法在这类函数中自动推导与T对应的双倍宽度类型DT?
另外我看到一份C提案文档(P0103r1),它原本应该解决这类问题,但没找到主流C编译器对它的实现信息。
解决方案
自定义类型特征实现自动推导
可以自行实现一个类型特征模板,映射基础整数类型到对应的双倍宽度类型,让函数无需手动指定第二个模板参数:
#include <cstdint> // 定义双倍宽度类型映射的类型特征 template<typename T> struct double_width; // 特化基础整数类型的映射 template<> struct double_width<int32_t> { using type = int64_t; }; template<> struct double_width<int64_t> { using type = __int128; }; template<> struct double_width<uint32_t> { using type = uint64_t; }; template<> struct double_width<uint64_t> { using type = unsigned __int128; }; // 简化类型别名,方便使用 template<typename T> using double_width_t = typename double_width<T>::type; // 修改后的multiply函数,自动获取DT类型 template <typename T> T multiply(T x, T y, T mod) { using DT = double_width_t<T>; return (static_cast<DT>(x % mod) * (y % mod)) % mod; }
调用时只需传入参数,编译器会自动推导T,并通过类型特征获取对应的DT:
z = multiply(x, y, m);
注:__int128是GCC、Clang及新版MSVC支持的扩展类型,用于处理64位整数的双倍宽度计算。
更通用的位宽适配实现
如果需要适配更多位宽的整数类型,可以基于类型的位宽和符号属性自动推导:
#include <type_traits> #include <cstdint> template<typename T> struct double_width { static constexpr size_t bit_width = sizeof(T) * 8; using type = std::conditional_t< std::is_signed_v<T>, std::conditional_t<bit_width == 32, int64_t, __int128>, std::conditional_t<bit_width == 32, uint64_t, unsigned __int128> >; }; template<typename T> using double_width_t = typename double_width<T>::type;
这种实现会根据输入类型的位宽和符号,自动选择对应的双倍宽度类型。
关于P0103r1提案
你提到的这份提案旨在为C++标准库添加std::double_width等类型特征,标准化双倍宽度类型的自动推导逻辑,但目前该提案尚未被纳入正式标准,主流编译器也未提供相关的标准库支持,因此暂时只能依赖自定义实现。
内容的提问来源于stack exchange,提问作者HEKTO
相关产品推荐
相关产品推荐

