- ๋ฐ๋ณต์๋ STL์ ์ดํดํ๋๋ฐ์ ํ์์ ์ธ ๊ฐ๋
์ด๋ค.
- STL์ด ์ ๊ณตํ๋ ๋ฐ๋ณต์๋ 4๊ฐ์ง๋ค. (iterator, const_iterator, reverse_iterator, const_reverse_iterator)
- ์ด ํฐ์ฅ์์๋ ๊ฐ ๋ฐ๋ณต์๋ค์ ํน์ฑ๊ณผ, ๋ฐ๋ณต์๋ฅผ ํจ์จ์ ์ผ๋ก ์ฐ๋ ๋ฐฉ๋ฒ์ ๋ค๋ฃฐ ๊ฒ์ด๋ค.
Contents
- 1. Item26. Prefer iterator to const_iterator, reverse_iterator, and const_reverst_iterator.
- 2. Item27. Use distance and advance to convert a container's const_iterators to iterators.
- 3. Item28. Understand how to use a reverse_iterator's base iterator
- 4. Item29. Consider istreambuf_iterators for character-by-characer input.
1.1. ๊ฐ๊ฐ์ ๋ฐ๋ณต์๊ฐ ์๋ฏธํ๋ ๊ฒ ¶
- container<T>::iterator, reverse_iterator : T*
- container<T>::const_iterator, const_reverse_iterator : const T*
- reverse๋ ๋ค์์๋ถํฐ ์์ผ๋ก ์ํํจ. ์๋๊ฑด ์์์๋ถํฐ ๋ค๋ก
1.2. iterator๋ฅผ ์จ์ผํ๋ ์ด์ ¶
- ๋๋ถ๋ถ์ ๋ฉ์๋๋ค์ ์ธ์๊ฐ iteratorํ์
์ด๋ค.
- ๋ค๋ฅธ iterator๋ก๋ถํฐ iterator๋ก ์์์ ์ธ ๋ณํ์ด ๊ฐ๋ฅํ๋ค.
1.3. ๊ฒฐ๋ก ¶
- ์ด๋ฐ ํผ์กํจ์ ๊ฒช๊ณ ์ถ์ง ์๋ค๋ฉด ๊ทธ๋ฅ ๋ด๊ฑฐ ์ฐ์ง ๋ง๊ณ iterator ์ฐ์๋ ๊ฒ์ด๋ค.
- ๋ด ํด์์ด ์๋ชป๋์ง ์์๋ค๋ฉด, const_iterator๋ ๋ง์ฝ์ ์์ง๊ฐ ์๋ ๋์ด๋ผ๊ณ ๊น์ง ํํํ๊ณ ์๋ค.
2.1. ์๋ก ¶
- const_iterator๋ ๋ ์ ์์ผ๋ฉด ์ฐ์ง ๋ง๋ผ๊ณ ํ์ง๋ง, ์ด์ฉ์ ์์ด ์จ์ผํ ๊ฒฝ์ฐ๊ฐ ์๋ค.
- ๊ทธ๋์ ์ด๋ฒ Item์์๋ const_iterator -> iterator๋ก ๋ณํํ๋ ๋ฒ์ ์ค๋ช
ํ๊ณ ์๋ค. ๋ฐ๋์ ๊ฒฝ์ฐ๋ ์์์ ์ธ ๋ณํ์ด ๊ฐ๋ฅํ์ง๋ง, ์ด๊ฑด ์๋๋ค.
- ๋ค์์ C++์ casting์ ๊ดํ ๋ฌด์จ ํจ์ถ์ ์ธ ์๋ฏธ๊ฐ ๋ด๊ธด ๋ง์ ํ๊ณ ์๋๋ฐ.. ์์๋๋ถ์ ์ข ๊ฐ๋ฅด์ณ ์ฃผ์ธ์. ์ด๋ฐ์๊ฐ์ ๊ฐ์ง๊ณ ์๋๊ฒ์ ๋ํด ๋ถ๋๋ฌ์ ํ๋ผ๋ค์.
- ์๋ฌธ : "When all else fails, get a bigger hammer."
- ์๋ฌธ : "When all else fails, get a bigger hammer."
2.2. ์๋ชป๋ ๋ฐฉ๋ฒ๋ค ¶
~cpp // iterator์ const_iterator๋ฅผ ๊ฐ๊ฐ Iter, CIter๋ก typedefํด๋์๋ค๊ณ ํ์. CIter ci; ... Iter i(ci); // ์๋๋ค. ์์์ ์ธ ํ๋ณํ์ ์ฑ๋ฆฝํ์ง ์๋๋ค. ... Iter i( const_cast<Iter>(ci) ) // ์ญ์ ์๋๋ค. vector์ string์์๋ ๋ ์ง๋ ๋ชจ๋ฅด์ง๋ง... ๋ณ๋ฃจ ์ถ์ฒํ์ง๋ ์๋๊ฒ ๊ฐ๋ค.
- ๋ฐ์๊ป ์๋๋ ์ด์ ๋ iterator์ const_iterator๋ ๋ค๋ฅธ ํด๋์ค์ด๋ค. ์์๊ด๊ณ๋ ์๋ ํด๋์ค๊ฐ ํ๋ณํ ๋ ๋ฆฌ๊ฐ ์๋ค.
- string, vector๊ฐ ๋ ์๋ ์๋ ์ด์
- vector<T>::iterator๋ T*์ typedef, vector<T>::const_iterator๋ const T*์ typedef์ด๋ค. (ํด๋์ค๊ฐ ์๋๋ค.)
- string::iterator๋ char*์ typedef, string::const_iterator๋ const char*์ typedef์ด๋ค. ๋ฐ๋ผ์ const_cast<>๊ฐ ํตํ๋ค. (์ญ์ ํด๋์ค๊ฐ ์๋๋ค.)
- vector<T>::iterator๋ T*์ typedef, vector<T>::const_iterator๋ const T*์ typedef์ด๋ค. (ํด๋์ค๊ฐ ์๋๋ค.)
- ํ์ง๋ง reverse_iterator์ const_reverse_iterator๋ typedef์ด ์๋ ํด๋์ค์ด๋ค. const_cast<์๋๋ค>.
2.3. ํด๊ฒฐ์ฑ ¶
~cpp Iter i(d.begin()); // d๋ ์ด๋ค ์ปจํ ์ด๋์ ์ธ์คํด์ค๋ค. advance(i, distance(i,ci)); // ์๋ ๊ฒ ํ๋ฉด ๋๋ค.... ์ธ์ค ์์๋๋ฐ ๋ฐ์ ๋ ์๋๋ค๊ณ ์จ์๋ค--;
- ์ ์๋๋๋ฉด, distance์ ์ธ์๋ ๋์ iterator๋ค. const_iterator๊ฐ ์๋๋ค.
~cpp advance(i, distance<CIter>(i,ci)); // ์ด๋ ๊ฒ ํ๋ฉด ์ง์ง ๋๋ค.
2.4. ์ก๋ด ¶
- ์ ๋ง ๋ณ๊ฑธ ๋ค ์ค๋ช
ํ๋ค๋ ์๊ฐ์ด ๋ ๋ค. ๋ชจ๋ฅด๊ณ ์์์ผ๋ฉด ์์ธ ๊ฒ๋ค๋, ๊ดํ ๋ค์ค์
๋ด์ ์ด๊ฑฐ ์ฐ์ง ๋ง์๋ผ ํ๋ ์คํ๋ ค ๋ ํท๊ฐ๋ฆฐ๋ค๋--;
3.1. ์์ ¶
~cpp vector<int> v; ... // v์ ์ฐจ๋ก๋๋ก 1~5๊น์ง ์ง์ด๋ฃ๋๋ค. typedef vector<int>::reverse_iterator VIRI; VIRI ri = find(v.rbegin(), v.rend(), 3); // ๊ฑฐ๊พธ๋ก ์ํํ๋ฉด์ 3์ ์ฐพ๋๋ค. typedef vector<int>::iterator VIIT; VIIT i(ri.base()); // ์์์๋ ๋งํ์ง๋ง reverse ์๋ฆฌ์ฆ์ base()๋ฉ์๋๋ฅผ ํธ์ถํด์ฃผ๋ฉด ๊ทธ๋ฅ ์๋ฆฌ์ฆ๋ก ๋ฐ๋ ๋ฐ๋ณต์๋ฅผ ๋ฆฌํดํด์ค๋ค.
rend() | ri | rbegin() | ||||
1 | 2 | 3 | 4 | 5 | ||
begin() | i | end() |
- ์ด์งธ ๊ทธ๋ฆผ์ด ์ข ์ด์ํ๊ธด ํ๋ฐ..--; ๊ฐ๊ฐ์ ๋ฐ๋ณต์๊ฐ ๊ฐ๋ฅดํค๋ ์์น๋ฅผ ๋ํ๋ธ ๊ฒ์ด๋ค. ๋ณด๋ฉด ์๊ฒ ์ง๋ง ri์์ base()๋ฅผ ํธ์ถํด์คฌ๋๋ฐ๋ ๊ฐ๋ฅดํค๋๊ฒ ๊ฐ์ง๊ฐ ์๋ค.
- ๊ฒฐ๋ก ๋ถํฐ ๋งํ์๋ฉด, base()๋ฉ์๋๊ฐ ์ํ๋ ๋ฐ๋ณต์๋ฅผ ๋ฆฌํดํด์ฃผ๋๊ฑด ์๋๋ค. ์ฝ์
ํ ๋๋ ๋์ง๋ง, ์์๋ฅผ ์ง์ธ๋๋ ๊ผฌ์ธ๋ค.
- ๋ง์ฝ์ ri๊ฐ ๊ฐ๋ฅดํค๋ ์์น์๋ค ์๋ก์ด ์์๋ฅผ ์ฝ์
ํ๊ณ ์ถ๋ค๊ณ ํ์. ํ์ง๋ง insert ๋ฉ์๋๋ reverse_iterator๋ ์ธ์๋ก ๋ฐ์ง ์๋๋ค. iteratorํ๋ง ์ธ์๋ก ๋ฐ๋๋ค. ์ฆ ์ง์ ์ ๋ชปํ๋ค๋ ๊ฒ์ด๋ค. ์ง์ธ๋๋ ์ด์ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. ๊ทธ๋์ base()๋ฅผ ์ฐ๋ ๊ฒ์ด๋ค.
- 99๋ฅผ i๊ฐ ๊ฐ๋ฅดํค๋ ์์น์ ์ฝ์
ํ๋ค๊ณ ํ๋ฉด(reverse์๋ฆฌ์ฆ๋ ์ธ์๋ก ๋ชป ๋ฃ๋๋ค.) ์ด๋ ๊ฒ ๋ ๊ฒ์ด๋ค.
1 | 2 | 3 | 99 | 4 | 5 |
- ์ฝ์
์ ๋ฌธ์ ์์ด ๋์์ง๋ง.. ๋ง์ฝ์ erase()๋ฅผ ํธ์ถํ๋ค๋ฉด? ๋ 3์ ์ง์ฐ๊ณ ์ถ์๋ฐ base()ํธ์ถํด์ iterator๋ฒ์ ผ์ผ๋ก ๋ฃ์ด์ฃผ๋ฉด 4๊ฐ ๋ ์๊ฐ ๊ฒ์ด๋ค. ์ด๋ป๊ฒ ํด์ผํ๋๊ฐ?
- ํด๊ฒฐ์ฑ
์
~cpp v.erase( (++ri).base() ); // ๋. ์ด๋ฌ๋ฉด ri๋ 2๋ฅผ ๊ฐ๋ฅดํค๊ฒ ๋๊ณ base() ํธ์ถํ ๋ฆฌํด๋๋ ๋ฐ๋ณต์๋ 3์ ๊ฐ๋ฅดํจ๋ค. ๊ทธ๊ฑธ ์ง์ฐ๋ฉด ๋๋ค.