C++11 编写模板以选择更大的整数类型的方法
C++11 way to write template for picking bigger integer type?
在 C++11 的编译时,在一个接受 2 个模板参数的模板函数中,这两个参数都必须是无符号整数类型,我想让一个局部变量具有两个模板参数中任何一个具有更多位的类型。在 C++03 中,我可能会写这样的东西:
template<bool, class T, class U>
struct pick_first;
template<class T, class U>
struct pick_first<true, T, U> {
typedef T type;
};
template<class T, class U>
struct pick_first<false, T, U> {
typedef U type;
};
template<class T, class U>
struct pick_bigger {
typedef typename pick_first<(sizeof(T) >= sizeof(U)), T, U>::type type;
};
// usage
template<class uintX_t, class uintY_t>
void foo() {
typename pick_bigger<uintX_t, uintY_t>::type mylocal = 0;
// insert doing stuff with mylocal here
}
我能否利用任何新的 C++11 功能来简化此操作?我知道我可以使用可变参数模板来使其不仅适用于对类型,而且无需使用pick_first我可以编写大量专用化来使其适用于新的int_leastX_t和int_fastX_t类型。但我很好奇是否有一种更好的方法。也许以某种方式利用auto/constexpr/decltype?
你的pick_first在C++11中只是std::condition,所以你可以写
template<class T, class U>
struct wider {
using type = typename std::conditional<sizeof(T) >= sizeof(U), T, U>::type; // I'm using the C++11 type alias feature 1) to educate people about them and 2) because I like them better than typedefs.
};
如果你只想要一个适合保存涉及两种类型的表达式结果的类型,并且不一定需要两种类型中的一种,那么std::common_type
,或者也许是auto
,是最好的解决方案:
template<class uintX_t, class uintY_t>
void foo() {
typename std::common_type<uintX_t, uintY_t>::type mylocal = 0;
// insert doing stuff with mylocal here
}
// or
template<class uintX_t, class uintY_t>
void foo(uintX_t x, uintY_t y) {
auto mylocal = x + y;
}
并且您对pick_bigger的实现缺少一个typename
:typedef typename pick_first<(sizeof(T) >= sizeof(U)), T, U>::type type;
这是我
的解决方案,可以从N种类型中选择最广泛的类型,直到模板递归限制。
我还包含了最窄的代码。
template <typename TFirst, typename... TOther>
struct widest {
private:
using rhs_recursive_type = typename widest<TOther...>::type;
public:
using type =
typename std::conditional<sizeof(TFirst) >= sizeof(rhs_recursive_type),
TFirst, rhs_recursive_type>::type;
};
template <typename TFirst>
struct widest<TFirst> {
using type = TFirst;
};
template <typename TFirst, typename... TOther>
struct narrowest {
private:
using rhs_recursive_type = typename widest<TOther...>::type;
public:
using type =
typename std::conditional<sizeof(TFirst) <= sizeof(rhs_recursive_type),
TFirst, rhs_recursive_type>::type;
};
template <typename TFirst>
struct narrowest<TFirst> {
using type = TFirst;
};
由于两种类型都是无符号的,因此只需执行decltype( T1() + T2() )
即可。
相关文章:
- 整数类型应该显式转换(例如"int"到"无符号")还是只会增加混乱?
- 涉及旧式枚举和整数类型的重载解析
- 将字符串转换为整数类型T,检查是否存在溢出
- 整数文本太大,无法用任何整数类型表示--C++
- isdigit(c) - 字符或整数类型?
- 为什么对小于 4 个字节的整数类型的位操作会发生意外行为?
- C++模板专用化 - 将其他整数类型委托给uint64_t
- 何时应使用 C++ 固定宽度整数类型,它们如何影响性能?
- 根据浮点数选择最小整数类型
- 为什么 QVariant 将字符类型视为整数类型
- 我们可以在整数类型的双指针中分配2D整数数组的地址吗?怎么可能
- 默认情况下,决定整数类型是唱歌或无符号的类型
- 是否可以根据类型是整数类型还是浮点类型重载模板函数
- 使用固定整数类型的安全性
- 如何使用条件来检查类型名 T 是否是 C++ 中浮点类型的整数类型
- C++文本整数类型
- 哪种整数类型可以安全且便携式用于始终保持指针值
- 检测整数类型变量上的空白输入
- 为什么对Chrono :: Nanseconds的表示类型是签名的整数类型
- 如何处理警告:从较小的整数类型int转换为int*