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

时间:2020-06-29 20:52:15

标签: c++ atomic decltype

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

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?

2 个答案:

答案 0 :(得分:7)

这是默认行为。来自[numeric.limits]

  1. 对于在numeric_­limits模板中声明为static constexpr的所有成员,专业化必须以可以用作常量表达式的方式定义这些值。
  2. 默认的numeric_­limits<T>模板应具有所有成员,但是具有0false值。
  3. 应为每种算术类型(浮点数和整数)(包括bool)提供专门化。对于is_­specialized的所有此类专业化,成员true应为numeric_­limits
  4. 在cv限定类型cv numeric_­limits上,T的每个专业化成员的值应等于在非限定类型{{1}上的专业化的对应成员的值}。
  5. 诸如T之类的非算术标准类型不应具有特殊化。

因此,由于complex<T>是非算术类型,因此第6款将不具有特殊化,这意味着第3款会起作用,您获得的所有值将是std::atomic<T>或{{ 1}}。

答案 1 :(得分:4)

std::numeric_limits<T>在没有针对T的专业化时具有默认实现。

因此,当T=std::stringT=std::atomic<size_t>时,std::numeric_limits仍然可以正常编译,只会报告默认值。

但是,在buggyGetMax()函数内部(返回uint64_t的情况下,返回std::numeric_limits<std::string>::max()不会编译,因为max()返回了一个空的std::string隐式转换为uint64_t。但是std::atomic<size_t>确实隐式转换为uint64_t,这就是为什么返回std::numeric_limits<std::atomic<std::size_t>>::max()进行编译的原因。只是不会返回您期望的值。

相关问题