C++如何获取标量最值?适配uint系列类型的单元测试优化需求
问题
我们的单元测试用来验证变量的最值,但当被测变量的底层数据类型变更时(比如把uint8_t height改成uint16_t height),必须同步更新测试代码——前提是我们能发现且记得修改。针对uint8_t、uint16_t、uint32_t、uint64_t这类无符号整数类型,有没有一种单元测试写法,能直接获取变量的最值,不用因为类型变更而修改测试代码?只需要支持这类简单场景就行,额外功能算加分项。另外,C++有没有原生方法可以获取标量的最值?
一、适配无符号整数的单元测试写法
核心思路是靠类型自动推导,让测试代码跟着变量类型走,不用硬写死具体类型的最值。
1. 极简写法:用C++标准库+类型推导
直接结合<limits>和decltype就能搞定,不用自己造轮子:
#include <limits> // 假设被测变量是height,类型任意无符号整数 uint16_t height; // 验证最大值边界 ASSERT_EQ(std::numeric_limits<decltype(height)>::max(), get_max_height()); // 验证最小值边界(无符号整数最小值固定是0) ASSERT_EQ(std::numeric_limits<decltype(height)>::min(), get_min_height());
不管height改成uint8_t还是uint64_t,这段测试代码完全不用改,decltype会自动推导变量类型,std::numeric_limits负责返回对应类型的最值。
2. 自定义模板函数(更直观的调用方式)
如果觉得上面的写法有点长,可以封装成模板函数,调用时直接传变量:
#include <cstdint> #include <type_traits> template<typename T> constexpr typename std::enable_if<std::is_unsigned<T>::value, T>::type get_max(const T&) { return static_cast<T>(-1); // 无符号整数取-1会溢出得到最大值 } template<typename T> constexpr typename std::enable_if<std::is_unsigned<T>::value, T>::type get_min(const T&) { return 0; }
测试时直接传变量就行,连decltype都不用写:
uint32_t width; ASSERT_EQ(get_max(width), get_max_width()); ASSERT_EQ(get_min(width), get_min_width());
加分项:编译期类型校验
如果想防止变量被改成有符号整数(避免测试逻辑失效),可以加static_assert做编译期检查:
uint8_t height; static_assert(std::is_unsigned<decltype(height)>::value, "变量必须是无符号整数类型"); ASSERT_EQ(std::numeric_limits<decltype(height)>::max(), get_max_height());
一旦变量类型改成int这类有符号类型,编译时直接报错,提前发现问题。
二、C++原生获取标量最值的方法
C++11及以后的标准库提供了<limits>头文件,里面的std::numeric_limits就是原生的标量最值获取工具,支持所有标准标量类型(无符号/有符号整数、浮点数等):
#include <limits> // 获取无符号整数最值 uint8_t max_u8 = std::numeric_limits<uint8_t>::max(); uint16_t min_u16 = std::numeric_limits<uint16_t>::min(); // 也支持有符号整数和浮点数 int max_int = std::numeric_limits<int>::max(); double min_double = std::numeric_limits<double>::min();
这个方法完全是C++原生支持,不需要依赖第三方库,兼容性拉满。
内容的提问来源于stack exchange,提问作者Mawg
相关产品推荐
相关产品推荐

