【发布时间】:2016-02-12 22:16:03
【问题描述】:
为std::string创建end(str)+1的迭代器是否有效?
如果不是,为什么不是?
这个问题仅限于 C++11 及更高版本,因为在 C++11 之前,数据已经存储在一个连续块中,但很少见的 POC 玩具实现中,数据没有 以这种方式存储。
我认为这可能会有所不同。
std::string 与我推测的任何其他标准容器之间的显着区别在于,它始终包含比其 size(零终止符)多一个元素,以满足 .c_str() 的要求。
21.4.7.1 basic_string 访问器[string.accessors]
const charT* c_str() const noexcept; const charT* data() const noexcept;1 返回:一个指针
p,使得p + i == &operator[](i)对应[0,size()]中的每个i。
2 复杂性:恒定时间。
3 要求:程序不得更改字符数组中存储的任何值。
尽管如此,即使它应该恕我直言,保证所述表达式是有效的,为了与零终止字符串的一致性和互操作性,如果没有别的,我发现的唯一一段对此表示怀疑:
21.4.1 basic_string 一般要求[string.require]
4
basic_string对象中的类字符对象应连续存储。也就是说,对于任何basic_string对象s,身份&*(s.begin() + n) == &*s.begin() + n应适用于n的所有值,这样0 <= n < s.size()。
(所有引用均来自 C++14 最终草案 (n3936)。)
【问题讨论】:
-
我很确定如果你增加结束迭代器,结果是未定义的行为。
-
不要试图打破抽象。不要假设末尾有 0,除非您致电
c_str()。 -
也许问题的要点是
std::string是否有效地允许*end(str)。在实践中,assert(*end(str) == '\0')应该永远不会失败,但它是正确的 C++11 吗? -
@ZanLynx:嗯,
string_ref不是string。并且有充分的理由,它没有后者提供的额外保证。 -
@user3164339
length和size相同:en.cppreference.com/w/cpp/string/basic_string/size
标签: c++ string iterator language-lawyer stdstring