为什么 numeric_limits<atomic<X>> 不会编译失败?

Why does numeric_limits<atomic<X>> not fail to compile?

我刚刚通过针对以下表达式测试值创建了一个错误:

std::numeric_limits<decltype(allocationCount)>::max()

在此上下文中,allocationCountstd::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]

  1. 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.
  2. The default numeric_­limits<T> template shall have all members, but with 0 or false values.
  3. 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.
  4. 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.
  5. Non-arithmetic standard types, such as complex<T>, shall not have specializations.

因此,由于 std::atomic<T> 是非算术类型,因此第 6 段不应有专门化,这意味着第 3 段开始起作用,您获得的所有值都将是 0false.

std::numeric_limits<T> 在没有针对 T.

的特化时具有默认实现

因此,当 T=std::stringT=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 您期望的值。