【问题标题】:What does "[ptr, ptr+len) must be a valid range" mean?“[ptr, ptr+len) 必须是有效范围”是什么意思?
【发布时间】:2018-10-31 10:25:52
【问题描述】:

在 c++ 标准的各个地方,这句话:

要求:[p, p + len) 是一个有效范围。

(其中 p 是一个指针,len 是一个数字)。

迭代器的替代版本是:

要求:[first, last) 是一个有效范围。

这是什么意思?

【问题讨论】:

  • 您能详细说明一下吗?你不明白什么?
  • 人力资源部。我找了这个问题,并没有找到副本。其他人比我更擅长搜索。我也准备好了答案。
  • 这些是非常糟糕的欺骗目标,完全错过了“有效范围”部分。重新开放。
  • “有效”表示允许访问的范围,不会导致 UB。
  • 如果混淆是关于区间符号,那么this is a possible dupe。

标签: c++ stl language-lawyer


【解决方案1】:

这意味着first包含和p+len或last独占之间的所有内容都必须有效。

这一切都取决于这样一个事实,即 C++ 允许存在数组末尾的指针,只要您只使用它们来引用数组的“末尾”而不取消引用它们。

如果我有:

int my_array[10];

int* first = &my_array[0];
int* last = &my_array[10];

那么first 和last 代表一个有效范围,即使last 在技术上指向无效的地方。

同样的原则也适用于迭代器,其中容器的end() 实际上根本不是容器数据的一部分。

乍一看,这一切可能看起来很奇怪,但这种表示范围的方式允许以理智的方式处理空范围。

【讨论】:

  • 这也意味着你可以围绕一个变量形成一个范围:int a; int* begin = &a; int* end = &a + 1; :)
【解决方案2】:

我认为C++17标准的相关部分在这里

27.2.1 一般[ iterator.requirements.general ]

...

8 当且仅当存在有限的应用程序序列时,从迭代器 i 调用迭代器 j可达表达式++i 使得i == j。如果j 与i 相比可达,则它们指的是相同序列的元素。

9 库中大多数对数据结构进行操作的算法模板都有使用范围的接口。范围是一对指定计算开始和结束的迭代器。范围[i, i) 是一个空范围;一般来说,[i, j) 范围是指数据结构中的元素,从i 指向的元素开始,直到但不包括j 指向的元素。当且仅当从i 可以到达j 时,范围[i, j) 才有效。将库中的函数应用于无效范围的结果未定义。

所以提取相关部分:

8 当且仅当存在有限的应用程序序列时,从迭代器 i 调用迭代器 j可达表达式++i 使得i == j...

9 ... 范围[i, j) 有效当且仅当j 可以从i 到达...。

因此,“有效范围”似乎是一对 迭代器,它们属于 同一个容器(或数组),j 比i.

但也不要忘记:

一般来说,[i, j) 范围是指数据结构中的元素,从i 指向的元素开始,直到但不包括j 指向的元素。

所以i 和j 之间的所有迭代器(但不一定包括j)必须“在数据结构中” (即没有越界).

【讨论】:

  • [nullptr, nullptr) 是一个有效范围吗?
  • @ceztko 这是一个非常好的问题。 IMO 是的,它基于我的回答中引用的段落8:“当且仅当存在使 i = = j”。在这种情况下,“最终的应用程序序列”是零。
  • 在几个狂野的测试中,Microsoft STL 实现同意,[nullptr, nullptr) 是一个有效范围。例如string(nullptr, 0) 或string_view(nullptr, 0)。
  • @ceztko 实际上,根据我对cppreference.com的理解,这些看起来很好
猜你喜欢
  • 2018-04-09
  • 2012-03-24
  • 2013-03-05
  • 2014-03-02
  • 2014-07-11
  • 2021-09-18
  • 2013-08-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多