Enr*_*lis 7 c++ language-lawyer numeric-limits
这段代码编译并运行
#include <limits>
#include <iostream>
struct Foo {
int x;
};
static_assert(!std::numeric_limits<Foo>::is_specialized);
int main() {
std::cout << "---" << std::endl;
std::cout << std::numeric_limits<Foo>::lowest().x << std::endl;
std::cout << std::numeric_limits<Foo>::min().x << std::endl;
std::cout << std::numeric_limits<Foo>::max().x << std::endl;
std::cout << "---" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
它打印
---
0
0
0
---
Run Code Online (Sandbox Code Playgroud)
这些数字从哪里来?
在 cppreference 上我读到了
此信息是通过
std::numeric_limits模板的专业化提供的。标准库为所有算术类型提供了专业化
由此我推断,缺乏对给定类型的专门化Foo意味着我不允许将其用于Foo. 那么上面的输出只是UB的一种表现吗?或者是什么?
如果我在上面的代码中更改int为char,则输出为
---
---
Run Code Online (Sandbox Code Playgroud)
这对我来说是“什么?! s 去哪里了std::endl,首先???”
使用非专业化numeric_limits是明确定义的。该代码示例没有 UB。引用标准草案:
Run Code Online (Sandbox Code Playgroud)... static constexpr T min() noexcept { return T(); } static constexpr T max() noexcept { return T(); } static constexpr T lowest() noexcept { return T(); } ...对于
numeric_limits主模板,所有数据成员都是值初始化的,并且所有成员函数都返回一个值初始化的对象。[注 1:这意味着所有成员都有零或
false值,除非numeric_limits专门用于某种类型。-尾注]
std::numeric_limits值初始化所有成员或从成员函数返回值的主要模板,请参阅[numeric.limits.general]/3。如果模板不是专门针对所提供的类型,这就是您得到的结果。没有UB。
任何专业化都应设置is_specialized为true并且必须定义所有成员,并在适用的情况下使用合理的值,否则0请false参阅[numeric.limits.special]/1和[numeric.limits.general]/4。
有趣的是[numeric.limits.general]/4需要将标准专业化设置为is_specialized,true但我没有看到用户专业化的任何等效要求。
| 归档时间: |
|
| 查看次数: |
183 次 |
| 最近记录: |