【问题标题】:Is it guaranteed by C++ standard that std::basic_string::npos + 1 == 0?C++ 标准是否保证 std::basic_string::npos + 1 == 0?
【发布时间】:2014-10-16 11:12:41
【问题描述】:

我希望消除算法中的特殊情况,为此我想确保 std::string::npos + 10

在我测试过的所有实现中都是如此,在标准中搜索我发现以下内容:

namespace std {
  template<class charT, class traits = char_traits<charT>,
    class Allocator = allocator<charT> >
  class basic_string {
    // ...
    typedef typename allocator_traits<Allocator>::size_type size_type;
    // ...
    static const size_type npos = -1;
    ...
  };
}

allocator_traits&lt;Allocator&gt;::size_type 被定义为无符号整数类型。

所以,我想,我的问题归结为 (static_cast&lt;T&gt;(-1)) + 1 是否总是为无符号整数类型 T 提供 0

【问题讨论】:

  • numeric_limits&lt;T&gt;::max 呢?
  • 我猜是的,但我不确定。
  • 在 C++11 中你可以static_assert (std::string::npos + 1 == 0, "bizarre string::npos")
  • 可能是的,但编译器会将其优化为无,这对接下来将处理您的代码的人类程序员来说是一个有用的提醒。

标签: c++


【解决方案1】:

不,无符号整数类型的最大值加一不能保证给你零。

如果size_type 被定义为unsigned short,并且intunsigned short 更宽,则添加的LHS 将转换为RHS,并且您依赖于在LHS 类型中执行的添加。

更糟糕的是,但实际上发生这种情况的可能性要小得多,如果unsigned short 具有与int 相同数量的值完全相同,则加法会溢出并导致未定义的行为。

但是,您可以做的是添加1U,并将添加的结果转换回T。这应该在常见实现上生成完全相同的代码,但保证对所有人都有效。

【讨论】:

  • 如果sizeof(std::string::size_type) &gt;= sizeof(int) 升级为unsigned 并且行为得到保证。第三段 Worse yet, but… 不正确。
  • 这是小于int tho 的尺寸的特殊情况。
  • @DavidRodríguez-dribeas 准确地说,如果std::string::size_type的最大值大于int的最大值。是的,在这种情况下,加法将保证评估为零。至于“更糟糕”的部分,它有什么不正确的地方? (请记住,符号位不算作值位之一。我说的是USHORT_MAX == INT_MAX 的实现,正如我所指出的,这不太可能,但完全有效。)
猜你喜欢
  • 2012-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-05
  • 1970-01-01
  • 2017-10-15
相关资源
最近更新 更多