【发布时间】:2021-11-23 19:58:37
【问题描述】:
假设在您无法控制的头文件中有一个声明,如下所示:
static const uint16 MaxValue = 0xffff; // the type could be anything, static or not
在包含上述内容的文件中,您有如下代码:
int some_function(uint16 n) {
if (n > MaxValue) {
n = MaxValue;
}
do_something(n);
...
}
编译器会警告 if 语句总是错误的,因为n 不能大于 0xffff。
一种方法可能是删除代码。但是,如果以后有人想将 MaxValue 的值更改为更低的值,那么您只是引入了一个错误。
两个问题:
- 是否有任何 C++ 模板或技术可用于确保在不需要时删除代码(因为
MaxValue是 0xfff)并包括在内(当MaxValue不是 0xffff 时)? - 假设您要显式编写额外检查以查看
MaxValue是否等于该类型可以容纳的限制,是否有一种可移植的技术可用于识别MaxValue类型的最大值可以工作如果稍后MaxValue的代码被更改?- 含义:如何通过变量名称推断类型的最大值?
- 我不希望使用
limits.h或<limit>常量,例如USHRT_MAX,或者不明确使用std::numeric_limits<uint16>的事件。 - 可以使用
std:numeric_limits<MaxValue>之类的东西吗?
- 我不希望使用
- 含义:如何通过变量名称推断类型的最大值?
【问题讨论】:
-
关闭愚蠢的警告。
-
n不能大于0xffff,这样检查就没有意义了?你到底想做什么?听起来对我来说是个 xy 问题。 -
您可以使用
if constexpr在编译时消除未使用的代码。您可以使用decltype来获取模板中使用的变量的类型,例如:std::numeric_limits<decltype(MaxValue)>::max() -
我知道 n 不能大于类型的最大值,但我也知道我正在查看的代码(仅由我给出的示例表示)类型最大值可能会在未来发生变化。这就是为什么我希望能够适应它。感谢您的回答。
-
constexpr uint16_t MaxValue = 0xffff; ... if constexpr((std::numeric_limits<decltype(n)>::max)() > MaxValue) { if (n > MaxValue) { n = MaxValue; } } ...可以从 C++17 开始;这应该有望阻止编译器抱怨。不过,编译器优化几乎肯定会对二进制文件产生相同的效果。
标签: c++ numeric-limits