【问题标题】:INT_[MIN|MAX] limit macros vs numeric_limits<T>INT_[MIN|MAX] 限制宏与 numeric_limits<T>
【发布时间】:2011-04-07 10:29:28
【问题描述】:

在std::numeric_limits&lt;T&gt; 上使用数字限制宏(例如INT64_MAX)是否有任何论据?据我了解numeric_limits 在标准中,但宏仅在 C99 中,因此非标准。

【问题讨论】:

    标签: c++


    【解决方案1】:

    其他答案大多有正确的信息,但似乎需要为 C++11 更新。

    在 C++11 中,std::numeric_limits&lt;T&gt;::min()、std::numeric_limits&lt;T&gt;::max() 和 std::numeric_limits&lt;T&gt;::lowest() 都声明为 constexpr,因此它们可以在大多数与 INT_MIN 和公司相同的上下文中使用。我能想到的唯一例外是使用# 字符串化令牌进行编译时字符串处理。

    这意味着numeric_limits 可用于案例标签、模板参数等,并且您可以在通用代码中使用它(尝试在template&lt;typename T&gt; get_min(T t); 中使用INT_MIN 与LONG_MIN 对比)。

    C++11 还为 James Kanze 谈到的问题带来了解决方案,通过添加 std::numeric_limits&lt;T&gt;::lowest(),它为所有类型提供了最低的有限值,而不是整数类型的最低值和浮点的最低正值-点类型。

    【讨论】:

      【解决方案2】:

      肯定是 C++0x 之前的版本。 INT_MIN 和 INT_MAX 是整型常量表达式; numeric_limits&lt;int&gt;::min() 和 numeric_limits&lt;int&gt;::max() 不是。 &lt;climits&gt; 是标准 C++,除非您正在处理模板(您不知道它是 int 还是 long),否则真的没有理由为过于复杂的解决方案而烦恼。 (另外:如果您正在编写模板,请不要忘记 numeric_limits&lt;int&gt;::min() 和 numeric_limits&lt;double&gt;::min() 代表完全不同的属性;如果您想要最小的可能值,则需要 numeric_limits&lt;T&gt;::is_integer ? numeric_limits&lt;T&gt;::min() : -numeric_limits&lt;T&gt;::max()。)

      【讨论】:

      • 如果你想使用模板中的值,我要补充一点,整数常量表达式参数只计算在内。
      • @Xeo:这不是真的。当你初始化一个静态类时,它也很重要。
      • @MSalters, ?没有整数常量就不能初始化整数类静态?
      • 你可以,但是你需要在你的班级之外定义它。
      • @Xeo 作为模板参数,作为数组的维度,作为案例标签,可能还有一些我已经忘记的其他案例。一般来说,简单的规则是当你知道类型时使用简单的解决方案(INT_MAX等),当你不知道时使用复杂的解决方案(numeric_limits)。
      【解决方案3】:

      如果是 C++,使用numeric_limits,结束。

      编辑:好的,根据詹姆斯的评论,而不是“结束”。 - 模板和案例标签除外。但是,我看不到为最小值或最大值设置案例标签或它们的模板的用途,但我想我还没有看到所有可能性......

      我想我的意思是numeric_limits 模板比max() 和min() 更有用...

      【讨论】:

      • 在需要整数常量表达式的上下文中尝试。说实例化一个模板,或者在一个案例标签中。或者对于较小的类型,作为数组维度(UCHAR_MAX + 1 很常见)。
      • @James,嗯.. 好的,我将编辑模板和案例标签,但不确定数组尺寸...
      • 重要提示:由于 C++11 std::numeric_limits&lt;T&gt;::max() 是 constexpr,所以异常不再成立。
      【解决方案4】:

      尽管在 C++11 中,std::numeric_limits 中的常量是 constexpr,以便您可以在模板等中使用它们,但至少在一种情况下您必须使用来自 @ 的宏987654323@/&lt;cstdint&gt; 代替。是预处理器。在 C++ 中,预处理器与在 C 中一样受到限制,因此它不能使用普通变量,无论是 const 还是 constexpr 一个。更不用说结构的成员,更不用说模板结构了。因此,您不能执行以下操作:

      #include <cstddef>
      #include <limits>
      
      // Won't work!
      #if std::numeric_limits<std::size_t>::max() > std::numeric_limits<unsigned>::max()
      // ...
      #endif
      

      相反,您应该求助于以下工作(并且更具可读性!)变体:

      #include <cstdint>
      #include <climits>
      
      // Works fine
      #if SIZE_MAX > UINT_MAX
      // ...
      #endif
      

      【讨论】:

        【解决方案5】:

        在某些情况下(例如case 标签、非类型模板参数)需要一个数字常量,而numeric_limits 不支持这一点:numeric_limits&lt;int&gt;::max() 不是常量。在case 标签中,您必须改用INT_MAX。

        这很烦人,但我听说 C++11 会解决这个问题。

        【讨论】:

          猜你喜欢
          • 2020-05-01
          • 2014-09-09
          • 1970-01-01
          • 1970-01-01
          • 2014-01-05
          • 1970-01-01
          • 2011-02-15
          • 1970-01-01
          相关资源
          最近更新 更多