加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – `std :: string :: begin()`/`std :: string :: end()`的迭

发布时间:2020-12-16 03:42:33 所属栏目:百科 来源:网络整理
导读:#include string#include iostreamint main() { std::string s = "abcdef"; std::string s2 = s; auto begin = const_caststd::string const (s2).begin(); auto end = s2.end(); std::cout end - begin 'n';} 此代码将begin()const的结果与end()的结果混合
#include <string>
#include <iostream>

int main() {
    std::string s = "abcdef";

    std::string s2 = s;

    auto begin = const_cast<std::string const &>(s2).begin();
    auto end = s2.end();

    std::cout << end - begin << 'n';
}

此代码将begin()const的结果与end()的结果混合在一起.这些函数都不允许使任何迭代器无效.但是我很好奇是否要求end()不使iterator变量begin失效实际上意味着变量begin可以用于end.

考虑一下C8,std :: string的copy-on-write实现;非const begin()和end()函数会导致复制内部缓冲区,因为这些函数的结果可用于修改字符串.因此,上面的开始对s和s2都有效,但是使用非const end()成员会使它不再对s2(生成它的容器)有效.

上面的代码使用copy-on-write实现(例如libstdc)产生“意外”结果.而不是结束 – 开始与s2.size(),libstdc produces another number相同.

>导致开始不再是s2的有效迭代器,从中检索它的容器,构成’使迭代器无效’吗?如果你看一下迭代器的要求,它们在调用.end()之后似乎都保留了这个迭代器,所以也许begin仍然有资格作为一个有效的迭代器,因此没有被无效?
>上面的代码是否在C 98中定义得很好?在C 11中,禁止写入时复制实现?

根据我自己对规范的简要介绍,它看起来不明确,因此可能无法保证begin()和end()的结果可以一起使用,即使没有混合const和非const版本.

解决方法

如你所说,C 11在这方面与早期版本不同. C 11中没有问题,因为删除了所有允许写入时复制的尝试.在C 11之前,您的代码会导致未定义的行为;允许调用s2.end()使现有的迭代器无效(并且在g中完成,也可能仍然如此).

请注意,即使s2不是副本,标准也会允许它使迭代器无效.实际上,C 98的CD甚至可以使用f(s.begin(),s.end())或s [i] == s [j]这些未定义的行为.这只是在最后一刻才实现,并进行了更正,以便只有第一次调用begin(),end()或[]才能使迭代器无效.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读