<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Soul Of Free Loop &#187; 随机</title>
	<atom:link href="https://zohead.com/archives/tag/random/feed" rel="self" type="application/rss+xml" />
	<link>https://zohead.com</link>
	<description>Uranus Zhou&#039;s Blog</description>
	<lastBuildDate>Sat, 19 Jul 2025 15:42:46 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.8</generator>
	<item>
		<title>STL中const_iterator、reverse_iterator转换为iterator</title>
		<link>https://zohead.com/archives/stl-const-reverse-iterator/</link>
		<comments>https://zohead.com/archives/stl-const-reverse-iterator/#comments</comments>
		<pubDate>Fri, 25 May 2012 15:25:39 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[const_iterator]]></category>
		<category><![CDATA[iterator]]></category>
		<category><![CDATA[reverse_iterator]]></category>
		<category><![CDATA[STL]]></category>
		<category><![CDATA[Vector]]></category>
		<category><![CDATA[转换]]></category>
		<category><![CDATA[随机]]></category>

		<guid isPermaLink="false">http://zohead.com/?p=191</guid>
		<description><![CDATA[本文同步自（如浏览不正常请点击跳转）：https://zohead.com/archives/stl-const-reverse-iterator/ STL中的容器类（Container）一般提供了4个迭代器：iterator、const_iterator、reverse_iterator、const_reverse_iterator，对于 container&#60;T&#62; 而言，其中 const_iterator 相当于 const T *，const_iterator 指向的元素不能做修改操作。 STL 容器的 begin() 和 end() 默认都提供了 iterator 和 con [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>本文同步自（如浏览不正常请点击跳转）：<a href="https://zohead.com/archives/stl-const-reverse-iterator/" target="_blank">https://zohead.com/archives/stl-const-reverse-iterator/</a></p>
<p>STL中的容器类（Container）一般提供了4个迭代器：iterator、const_iterator、reverse_iterator、const_reverse_iterator，对于 container&lt;T&gt; 而言，其中 const_iterator 相当于 const T *，const_iterator 指向的元素不能做修改操作。</p>
<p>STL 容器的 begin() 和 end() 默认都提供了 iterator 和 const_iterator 的迭代器，相应的 rbegin() 和 rend() 则也分别提供了 reverse_iterator 和 const_reverse_iterator 的迭代器用于从容器的尾端反向遍历。</p>
<p>最近写的代码中刚好要用到 const_iterator 迭代器，发现由于 STL 提供的一些容器操作函数像 insert、erase 的参数必须为 iterator，这时就不能用 const_iterator 做参数（不能直接转换），以下为个人经验结果。</p>
<p><strong><span style="color: #ff0000;">1、const_iterator 转换为 iterator：</span></strong></p>
<p>iterator 可以隐式转换为 const_iterator，但反过来就不行，就算祭出强制类型转换的杀招应该也会编译报错，这是可以用折中的办法解决：</p>
<p><em><span style="color: #008000;">vector&lt;sss&gt; v_test;</span></em><br />
<em><span style="color: #008000;">vector&lt;sss&gt;::iterator i_test;</span></em><br />
<em><span style="color: #008000;">vector&lt;sss&gt;::const_iterator c_test;</span></em><br />
<em><span style="color: #008000;">...</span></em><br />
<em><span style="color: #008000;">c_test = ....</span></em><br />
<em><span style="color: #008000;">...</span></em><br />
<em><span style="color: #008000;">i_test = v_test.begin();</span></em><br />
<em><span style="color: #008000;">advance(i_test, distance&lt;vector&lt;sss&gt;::const_iterator&gt;(i_test, c_test));</span></em></p>
<p>i_test 指向第一个元素，先通过 distance 得到 c_test 和 i_test 的偏移量，然后用 advance 将 i_test 往后移对应的偏移量即可。注意 distance 的模板类型必须为 const_iterator 类型，否则按照 STL 的默认类型推导，distance 中的 i_test 和 c_test 类型不同还是会出现编译报错。</p>
<p>当然如果你想偷懒简单点，也可以这样写，道理是一样的，这时类型推导就显得很好用了：</p>
<p><em><span style="color: #008000;">i_test = v_test.begin() + (c_test - v_test.begin());</span></em></p>
<p><strong><span style="color: #ff0000;">2、reverse_iterator 转换为 iterator：</span></strong></p>
<p>对于 reverse_iterator 可以调用 base() 得到 “与之对应” 的 iterator（与上面的环境一样）：</p>
<p><em><span style="color: #008000;">vector&lt;sss&gt; v_test;</span></em><br />
<em> <span style="color: #008000;"> vector&lt;sss&gt;::iterator i_test;</span></em><br />
<em> <span style="color: #008000;"> vector&lt;sss&gt;::reverse_iterator r_test;</span></em><br />
<em> <span style="color: #008000;"> ...</span></em><br />
<em> <span style="color: #008000;"> r_test = ....</span></em><br />
<em> <span style="color: #008000;"> ...</span></em><br />
<em> <span style="color: #008000;"> i_test = r_test.base();</span></em></p>
<p>但需要注意的是由于 STL 的 begin() 和 end()、rbegin() 和 rend() 是两个半闭合的区间，end() 并不是最后一个元素，rend() 也不是第一个元素，因此 end() 和 rbegin()、rend() 和 begin() 之间都是差了一个元素的。我们来看看 STL 标准上 base() 的说明：</p>
<p><em><span style="color: #008000;">The base iterator is an iterator of the same type as the one used to construct the reverse_iterator, but pointing to the element next to the one the reverse_iterator is currently pointing to (a reverse_iterator has always an offset of -1 with regards to its base iterator).</span></em></p>
<p>也就是 reverse_iterator 的 base() 返回的元素都是 reverse_iterator 所指向元素的下一个元素，这也是前面 “与之对应” 加引号的原因。因此在使用时要特别注意，例如如果要删除 reverse_iterator 指向的元素就需要这样（因为 erase 必须要 iterator 类型的参数）：</p>
<p><em><span style="color: #008000;">v_test.erase((++r_test).base());</span></em></p>
<p><strong><span style="color: #ff0000;">3、关于随机访问容器：</span></strong></p>
<p>STL 中随机访问容器是一个迭代器类型为随机访问迭代器的可逆容器，它提供常量缓冲时间来访问随机元素。而可逆容器是一个有双向迭代器的前向容器，它可以向后向后迭代通过容器。</p>
<p>常用到的顺序容器是将单一类型的元素聚集起来，然后根据位置来存储和访问这些元素。顺序容器的元素排列次序与元素值无关，而是由元素添加到容器里的次序决定。</p>
<p>平时经常用的 string、vector、deque 之类就是典型的随机访问容器，map、set、list 之类的就不是。</p>
<p>因此需要注意 STL 中的 sort 等函数的参数必须是随机访问迭代器，所以对 map、set、list 等容器是无效的。</p>
<p>以上为个人见解，有任何问题欢迎指正交流咯 ^_^。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/stl-const-reverse-iterator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
