为什么 numeric_limits<atomic<X>> 不会编译失败?
Why does numeric_limits<atomic<X>> not fail to compile?
我刚刚通过针对以下表达式测试值创建了一个错误:
std::numeric_limits<decltype(allocationCount)>::max()
在此上下文中,allocationCount
是 std::atomic<std::size_t>
。
显然,上面提到的表达式compiles and evaluates to 0 on both Clang 10 and GCC 10:
#include <atomic>
#include <cstdint>
#include <limits>
#include <string>
static std::atomic<std::size_t> allocationCount = 0;
uint64_t buggyGetMax() {
return std::numeric_limits<decltype(allocationCount)>::max();
}
uint64_t correctGetMax() {
return std::numeric_limits<decltype(allocationCount)::value_type>::max();
}
我想用的是
std::numeric_limits<decltype(allocationCount)::value_type>::max()
产生我想要的值,即std::numeric_limits<std::size_t>::max()
。
我的问题是为什么 std::numeric_limits<decltype(allocationCount)>
还要编译?它不应该像 std::numeric_limits<std::string>
那样失败吗?
如果这是设计使然,为什么 max()
是 0?
这是默认行为。来自 [numeric.limits]
- For all members declared static constexpr in the
numeric_limits
template, specializations shall define these values in such a way that they are usable as constant expressions.
- The default
numeric_limits<T>
template shall have all members, but with 0
or false
values.
- Specializations shall be provided for each arithmetic type, both floating-point and integer, including bool. The member
is_specialized
shall be true
for all such specializations of numeric_limits
.
- The value of each member of a specialization of
numeric_limits
on a cv-qualified type cv T
shall be equal to the value of the corresponding member of the specialization on the unqualified type T
.
- Non-arithmetic standard types, such as
complex<T>
, shall not have specializations.
因此,由于 std::atomic<T>
是非算术类型,因此第 6 段不应有专门化,这意味着第 3 段开始起作用,您获得的所有值都将是 0
或false
.
std::numeric_limits<T>
在没有针对 T
.
的特化时具有默认实现
因此,当 T=std::string
和 T=std::atomic<size_t>
时,std::numeric_limits
仍然可以正常编译,它只会报告默认值。
但是,在您的 buggyGetMax()
函数内部,return 是 uint64_t
,returning std::numeric_limits<std::string>::max()
将无法编译,因为 max()
return 是一个空 std::string
,它不会隐式转换为 uint64_t
。但是 std::atomic<size_t>
确实隐式转换为 uint64_t
,这就是 returning std::numeric_limits<std::atomic<std::size_t>>::max()
编译的原因。它只是不会 return 您期望的值。
我刚刚通过针对以下表达式测试值创建了一个错误:
std::numeric_limits<decltype(allocationCount)>::max()
在此上下文中,allocationCount
是 std::atomic<std::size_t>
。
显然,上面提到的表达式compiles and evaluates to 0 on both Clang 10 and GCC 10:
#include <atomic>
#include <cstdint>
#include <limits>
#include <string>
static std::atomic<std::size_t> allocationCount = 0;
uint64_t buggyGetMax() {
return std::numeric_limits<decltype(allocationCount)>::max();
}
uint64_t correctGetMax() {
return std::numeric_limits<decltype(allocationCount)::value_type>::max();
}
我想用的是
std::numeric_limits<decltype(allocationCount)::value_type>::max()
产生我想要的值,即std::numeric_limits<std::size_t>::max()
。
我的问题是为什么 std::numeric_limits<decltype(allocationCount)>
还要编译?它不应该像 std::numeric_limits<std::string>
那样失败吗?
如果这是设计使然,为什么 max()
是 0?
这是默认行为。来自 [numeric.limits]
- For all members declared static constexpr in the
numeric_limits
template, specializations shall define these values in such a way that they are usable as constant expressions.- The default
numeric_limits<T>
template shall have all members, but with0
orfalse
values.- Specializations shall be provided for each arithmetic type, both floating-point and integer, including bool. The member
is_specialized
shall betrue
for all such specializations ofnumeric_limits
.- The value of each member of a specialization of
numeric_limits
on a cv-qualified type cvT
shall be equal to the value of the corresponding member of the specialization on the unqualified typeT
.- Non-arithmetic standard types, such as
complex<T>
, shall not have specializations.
因此,由于 std::atomic<T>
是非算术类型,因此第 6 段不应有专门化,这意味着第 3 段开始起作用,您获得的所有值都将是 0
或false
.
std::numeric_limits<T>
在没有针对 T
.
因此,当 T=std::string
和 T=std::atomic<size_t>
时,std::numeric_limits
仍然可以正常编译,它只会报告默认值。
但是,在您的 buggyGetMax()
函数内部,return 是 uint64_t
,returning std::numeric_limits<std::string>::max()
将无法编译,因为 max()
return 是一个空 std::string
,它不会隐式转换为 uint64_t
。但是 std::atomic<size_t>
确实隐式转换为 uint64_t
,这就是 returning std::numeric_limits<std::atomic<std::size_t>>::max()
编译的原因。它只是不会 return 您期望的值。