CPP Module 08

CPP Module
All of C++98
Data Structure



1. ex00 (Easy find)

Day Specific Rule

์ด๋ฒˆ Module 08์—์„œ๋Š” Module 07์˜ ํ…œํ”Œ๋ฆฟ์„ ์ด์šฉํ•˜์ง€๋งŒ, ์˜ˆ์™ธ์ ์œผ๋กœ ์ด์ „ ์„œ๋ธŒ์ ํŠธ๋“ค๊ณผ ๋‹ฌ๋ฆฌ STL์„ ํ—ˆ์šฉํ•œ๋‹ค. STL์—์„œ ์†Œ๊ฐœ๋˜๋Š” Container, Iterator, Algorithm ๋ชจ๋“  ๊ฒƒ์„ ํ—ˆ์šฉํ•œ๋‹ค. ๋ฌผ๋ก  Module 08์—์„œ STL์„ ์ตœ๋Œ€ํ•œ ์ง€์–‘ํ•˜๋ฉด์„œ ์ฝ”๋“œ๋ฅผ ์™„์„ฑํ•ด๋„ ๋˜๊ฒ ์ง€๋งŒ, ์„œ๋ธŒ์ ํŠธ์—์„œ๋Š” STL์˜ ์‚ฌ์šฉ์„ ์ ๊ทน ๊ถŒ์žฅํ•˜๊ณ  ์žˆ๊ณ , ์ด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ํ–‰์œ„๋ฅผ ๊ฒŒ์œผ๋ฅด๋‹ค๊ณ  ํ‘œํ˜„ํ–ˆ์œผ๋‹ˆ STL์„ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•˜์—ฌ ์ž‘์„ฑํ•˜๋„๋ก ๋…ธ๋ ฅํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ์ฐธ๊ณ ๋กœ C++11์„ ์‚ฌ์šฉํ•˜๋ผ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ˆ ์•„๋ž˜์— ์„ค๋ช…๋œ std::begin, Parameter Pack, Lambda ๋“ฑ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜์ž.
ft_containers๋ฅผ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ๋งŽ์€ ๋„์›€์ด ๋œ๋‹ค.


์œ„์—์„œ ๋งํ•œ ๊ฒƒ์ฒ˜๋Ÿผ STL์€ Container, Iterator, Algorithm์„ ๋ชจ๋‘ ํฌํ•จํ•œ ๊ฐœ๋…์œผ๋กœ Standard Template Library์˜ ์•ฝ์ž์ด๋‹ค. ์ด๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ํ…œํ”Œ๋ฆฟ์„ ์ ์šฉํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋ฏ€๋กœ, ์ž„์˜์˜ ํƒ€์ž…์— ๋Œ€ํ•ด์„œ Container, Iterator, Algorithm์„ ๋ชจ๋‘ ์ง€์›ํ•œ๋‹ค.
๋Œ€์ฒด์ ์œผ๋กœ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด STLํ•˜๋ฉด Container๋ฅผ ๋– ์˜ฌ๋ฆฌ๊ณค ํ•˜๋Š”๋ฐ, ์ด๋Š” STL์˜ ๋‚˜๋จธ์ง€ ์š”์†Œ๋“ค์ด Container๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋ผ๊ณ  ๋ณผ์ˆ˜ ์žˆ๋‹ค. STL์˜ ๊ฝƒ์ธ Container๋Š” ์ž„์˜์˜ ํƒ€์ž…์— ๋Œ€ํ•ด ๋™์ž‘ํ•˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฒƒ๋“ค์„ ์ด์นญํ•œ๋‹ค. ๋˜ํ•œ Container ๋‚ด๋ถ€์—๋Š” Container์˜ ์š”์†Œ๋“ค์„ ์ˆœํšŒํ•˜๊ณ , ํƒ์ƒ‰ํ•˜๊ณ , ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก Iterator๋ฅผ ์ง€์›ํ•˜๋Š”๋ฐ, ์ด๋Š” Module 00์—์„œ ์–ธ๊ธ‰ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ํฌ์ธํ„ฐ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ์˜๋ฏธํ•œ๋‹ค. Iterator๋Š” Container๋ฅผ ํ†ตํ•ฉ๋œ ๋ฐฉ์‹์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ , Algorithm์— ๋Œ€ํ•ด์„œ ํ†ตํ•ฉ๋œ ์ฝ”๋“œ๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ƒ๊ธด ๊ฐœ๋…์ด๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ Algorithm์€ Container๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ผ๋ฐ˜์ ์ธ ๊ธฐ๋Šฅ๋“ค ๋ชจ๋‘๋ฅผ ์˜๋ฏธํ•˜๊ณ , <algorithm>์„ ํฌํ•จํ•˜๋ฉด์„œ ๊ฐ ํ•จ์ˆ˜๋“ค์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด std::swap, std::min, std::max, std::find, std::search, std::sort ๋“ฑ์ด ์กด์žฌํ•˜๊ณ , ์ด ์™ธ์—๋„ Container๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ์ •๋ง ๋งŽ์€ ํ•จ์ˆ˜๋“ค์ด ์žˆ๋‹ค. ํ•ด๋‹น ํ•จ์ˆ˜๋“ค์€ ์ฃผ๋กœ Container์˜ Iterator๋ฅผ ์กฐ์ž‘ํ•˜๋ฉด์„œ ๋™์ž‘ํ•˜๊ณ , ํ…œํ”Œ๋ฆฟ ํŠน์ˆ˜ํ™” (Template Specialization)๋ฅผ ํ†ตํ•ด ๋ฐฐ์—ด์— ๋Œ€ํ•ด์„œ๋„ ํฌ์ธํ„ฐ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋˜์–ด ์žˆ๋‹ค.
STL์— ๋Œ€ํ•œ ๊ฐ„๋žตํ•œ ์†Œ๊ฐœ๋Š” Module 00์˜ ex02์—๋„ ์žˆ์œผ๋‹ˆ ์ด๋ฅผ ์ฝ์–ด๋ณด์ž. ๊ทธ๋ฆฌ๊ณ  ํ…œํ”Œ๋ฆฟ ํŠน์ˆ˜ํ™”์— ๋Œ€ํ•ด์„  ๊ทธ ์•„๋ž˜์˜ ๊ธ€์„ ์ฝ์–ด๋ณด์ž.

std::find in STL

easyfind๋ผ๊ณ  ํ•˜๋Š” ํ•จ์ˆ˜๋Š” Container์—์„œ ํŠน์ • ๊ฐ’์„ ์ฐพ๋Š” ํ•จ์ˆ˜์ด๋‹ค. ํŠน์ • ๊ฐ’์„ ์ฐพ์ง€ ๋ชปํ•˜๋ฉด Exception์„ ๋˜์ง€๊ฑฐ๋‚˜, ๊ทธ์— ๊ฑธ๋งž๋Š” ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. ์ด ํŠน์„ฑ์„ ๊ณ ๋ คํ•˜์—ฌ, ํŠน์ • ๊ฐ’์„ ์ฐพ์•˜์„ ๋•Œ ์—ญ์‹œ ์–ด๋–ค ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค.
๋‚ด ๊ฒฝ์šฐ์— easyfind์˜ ์˜๋ฏธ๋Š” std::find ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ทธ ๊ฐ’์„ ์ฐพ์•„๋‚ด๊ณ , ์—†๋‹ค๋ฉด Exception์„ ๋˜์ ธ์ฃผ๋Š” ํ•จ์ˆ˜๋กœ ์ดํ•ดํ–ˆ๋‹ค. ๋ฌผ๋ก  easyfind์˜ ๊ฒฐ๊ณผ๋ฅผ ์ผ๋ฐ˜์ ์ธ Algorithm์˜ ํ•จ์ˆ˜๋“ค์ฒ˜๋Ÿผ Container์˜ ๋์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋„๋ก std::end๋ฅผ ์ ์šฉํ•œ Iterator๋ฅผ ๋ฐ˜ํ™˜ํ•ด๋„ ๋˜๊ฒ ์ง€๋งŒ, ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ •ํ™•ํ•˜๊ฒŒ std::find์™€ ์—ญํ• ์ด ๊ฒน์น˜๊ธฐ ๋•Œ๋ฌธ์— Exception์„ ๋˜์ง€๋„๋ก ๊ตฌํ˜„ํ–ˆ๋‹ค. ๋˜ํ•œ ์ด์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์ด std::find์™€ ๊ฒน์น˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ด์„œ std::find๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ, ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ํ•œ ๋ฒˆ ๋” Wrappingํ•œ ํ•จ์ˆ˜๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์—ˆ๋‹ค.
Exception์€ ์ง์ ‘ ๊ตฌํ˜„ํ•ด๋„ ์ข‹๊ฒ ์ง€๋งŒ, <stdexcept>์— ์žˆ๋Š” std::runtime_error๋ฅผ ์ด์šฉํ–ˆ๊ณ , ํ•ด๋‹น Exception์˜ ์ƒ์„ฑ์ž ์ธ์ž๋กœ ๋ณ„๋„์˜ ๋ฆฌํ„ฐ๋Ÿด ๊ฐ’์„ ๋„˜๊ฒจ์„œ what ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋กœ Exception์˜ ๋‚ด์šฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์—ˆ๋‹ค.

Parameter Pack (์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค! ์•Œ์•„๋งŒ ๋‘์„ธ์š”.)

int main(void) { std::deque<int> d; std::list<int> l; std::vector<int> v; test(d, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9); test(l, 6, 1, 2, 3, 4, 5, 6, 7, 8, 9); test(v, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9); return (0); }
๊ตฌํ˜„ํ•œ easyfind๋ผ๋Š” ํ•จ์ˆ˜๊ฐ€ int ํƒ€์ž…์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์ž„์˜์˜ Container์— ๋Œ€ํ•ด์„œ ๋™์ž‘ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์ฆ๋ช…ํ•˜๊ธฐ ์œ„ํ•ด ์ผ์ผ์ด Container๋ฅผ ๋งŒ๋“ค๊ณ , ๊ฐ’์„ ๋„ฃ๊ณ , easyfind๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ... ๋„ˆ๋ฌด ๋ฒˆ๊ฑฐ๋กญ์ง€ ์•Š์€๊ฐ€? ์ด๋ฅผ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•ด์„œ, ๊ธฐ์กด์— ์ƒ์„ฑํ•ด๋‘” Container๋ฅผ ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ๋ฐ›์•„ ์œ ๋™์ ์œผ๋กœ ๋‚ด๋ถ€ ์š”์†Œ ๊ฐ’์„ ํ• ๋‹นํ•˜์—ฌ easyfind๋ฅผ ํ˜ธ์ถœํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ•จ์ˆ˜ ์ด๋ฆ„์ด test๋ผ๊ณ  ํ•˜๋ฉด, main ํ•จ์ˆ˜์˜ ๋‚ด์šฉ์€ ์œ„ ์ฝ”๋“œ๊ฐ€ ์ „๋ถ€์ด๋‹ค.
template <typename C, typename... Arg> void test(C& container, int value, Arg... args) { container = C{args...}; try { typename C::iterator iter = easyfind(container, value); std::cout << "Value " << value << " found on Index " << std::distance(std::begin(container), iter) << std::endl; } catch (std::exception& e) { std::cerr << e.what() << std::endl; } }
์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ๋Œ€์ถฉ ์˜ˆ์ƒํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ธ๋ฐ, ์ฒซ ๋ฒˆ์งธ ์ธ์ž๊ฐ€ Container, ๋‘ ๋ฒˆ์งธ ์ธ์ž๊ฐ€ ์ฐพ์œผ๋ ค๋Š” ๊ฐ’, ์„ธ ๋ฒˆ์งธ ์ธ์ž๊ฐ€ Container๊ฐ€ ๋ณด์œ ํ•˜๋ ค๋Š” ์š”์†Œ๋“ค์ด ๋œ๋‹ค. Container์˜ ์‚ฌ์ด์ฆˆ๋ฅผ ๋ฏธ๋ฆฌ ์ •ํ•ด๋‘” ๊ฒƒ๋„ ์•„๋‹ˆ๊ณ , Container์˜ ์‚ฌ์ด์ฆˆ๋ฅผ ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ๋„˜๊ธด ๊ฒƒ๋„ ์•„๋‹Œ๋ฐ, ์œ„์™€ ๊ฐ™์€ ๊ตฌ๋ฌธ์ด ์–ด๋–ป๊ฒŒ ๊ฐ€๋Šฅํ•œ์ง€ ์˜๋ฌธ์ด ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ๊ตฌ๋ฌธ์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ์€ ํ…œํ”Œ๋ฆฟ์—์„œ Parameter Pack์„ ์ด์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. Parameter Pack์€ ...๋กœ ์ž‘์„ฑํ•œ ๋ถ€๋ถ„์„ ๋งํ•˜๋ฉฐ, ๊ทธ ์ƒ๊น€์ƒˆ๊ฐ€ Variadic Argument (๊ฐ€๋ณ€ ์ธ์ž)์™€ ๋งค์šฐ ์œ ์‚ฌํ•˜๋‹ค.
Parameter Pack์ด Variadic Arugment์™€ ๋น„์Šทํ•˜๊ฒŒ ์ƒ๊ฒผ๋‹ค๊ณ  ํ•ด์„œ ์„œ๋กœ ๋™์ผ ํ•œ ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. Variadic Arugment์˜ ๊ฒฝ์šฐ ์ธ์ž๋ฅผ ๋ช…์‹œํ•˜์ง€ ์•Š์œผ๋ฉด ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์€ ๊ตฌ๋ฌธ์ด๋ผ๊ณ  ๋ณด๊ธฐ ๋•Œ๋ฌธ์— ์ปดํŒŒ์ผ๋Ÿฌ ๊ฒฝ๊ณ ๋ฅผ ๋‚ด์ฃผ์ง€๋งŒ, Parameter Pack์€ ๊ธฐ๋ณธ์ ์œผ๋กœ 0๊ฐœ ์ด์ƒ์˜ ์ธ์ž๋ฅผ ์ง€์นญํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.
ํ…œํ”Œ๋ฆฟ ๋งค๊ฐœ๋ณ€์ˆ˜์—์„œ ์ด์šฉํ•œ Parameter Pack๊ณผ ํ…œํ”Œ๋ฆฟ ์ธ์ž๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ •์˜๋œ Parameter Pack์˜ ์ƒ๊น€์ƒˆ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ๋งค์šฐ ํ—ท๊ฐˆ๋ฆด ์ˆ˜ ์žˆ๋Š”๋ฐ, ํŽผ์นœ๋‹ค โ†’ ... โ†’ ๋„ฃ๋Š”๋‹ค ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ํŽธํ•˜๋‹ค. typename... Arg๋Š” ์—ฌ๋Ÿฌ ์ธ์ž๋“ค์„ ํŽผ์นœ๋‹ค โ†’ ... โ†’ ์—ฌ๋Ÿฌ ์ธ์ž๋“ค์„ Arg๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค๋กœ ์ดํ•ดํ•˜๋ฉด ๋˜๊ณ , Arg... args๋Š” ์—ฌ๋Ÿฌ ์ธ์ž๋“ค์„ ์˜๋ฏธํ•˜๋Š” Arg๋ฅผ ํŽผ์นœ๋‹ค โ†’ ... โ†’ ํŽผ์นœ ์—ฌ๋Ÿฌ ์ธ์ž๋“ค์„ args๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค๋กœ ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค. Arg๋Š” ํƒ€์ž…์ด๊ณ , args๋Š” ๋ณ€์ˆ˜์ด๋ฏ€๋กœ ์ •ํ™•ํ•˜๊ฒŒ ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ, ์ดํ•ดํ•˜๋Š”๋ฐ๋Š” ํฌ๊ฒŒ ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค. ๋˜ํ•œ args๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•  ๋•Œ๋Š” ๋์— ...๋ฅผ ๋ถ™์—ฌ ํŽผ์ณ์„œ ์—ฌ๋Ÿฌ ์ธ์ž๋กœ์จ ์ด์šฉํ•˜๋„๋ก ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
container = C{args...}๋Š” C๊ฐ€ ํŠน์ • ํƒ€์ž…์˜ Container๋ฅผ ์˜๋ฏธํ•˜๋ฏ€๋กœ, ํ•ด๋‹น ํƒ€์ž…์˜ ์ƒ์„ฑ์ž๋ฅผ Uniform Initialization์œผ๋กœ ํ˜ธ์ถœํ•˜์—ฌ container์— ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. Uniform Initialization์€ ์ค‘๊ด„ํ˜ธ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ธฐ๋ฒ•์„ ์˜๋ฏธํ•˜๋ฉฐ, ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ๋Š” std::initializer_list<T>๋ฅผ ์ธ์ž๋กœ ์ด์šฉํ•˜๋Š” ๊ตฌ๋ฌธ์ด ์‹คํ–‰๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ์ƒ์„ฑ์ž๋Š” ์ค‘๊ด„ํ˜ธ์— ๋ช…์‹œ๋œ ๊ฐ’๋“ค์„ ๋‚ด๋ถ€ ์š”์†Œ๋กœ ์ด์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ ๋‹ค. ๋”ฐ๋ผ์„œ ์ค‘๊ด„ํ˜ธ ๋‚ด์— ๋ช…์‹œํ•œ ๊ฐ’๋“ค์€ ๋ชจ๋‘ ํƒ€์ž…์ด ๊ฐ™์•„์•ผ std::initializer_list<T>๋กœ ์ธ์ž๋ฅผ ๋„˜๊ธธ ์ˆ˜ ์žˆ๋‹ค.

std::begin ? or Member Function begin ? (์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค! ์•Œ์•„๋งŒ ๋‘์„ธ์š”.)

์ด์ œ๊นŒ์ง€ ์˜ˆ์‹œ๋ฅผ ๋ณด๋ฉด std::begin์„ ์ฃผ๋กœ ์ด์šฉํ–ˆ๋Š”๋ฐ, Container๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•œ๋‹ค๋ฉด std::begin์„ ์“ฐ๋“  ๋ฉค๋ฒ„ ํ•จ์ˆ˜ begin์„ ์‚ฌ์šฉํ•˜๋“  ๊ฐœ์ธ์˜ ์„ ํƒ์— ๋‹ฌ๋ ค์žˆ๋‹ค. ํ•˜์ง€๋งŒ <algorithm>์—์„œ ์ œ๊ณตํ•˜๋Š” std::begin์˜ ์šฉ๋„๋Š” Container ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ฐฐ์—ด์— ๋Œ€ํ•ด์„œ๋„ ์ ์šฉ๋  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค. ์ฆ‰, std::begin ํ•จ์ˆ˜๊ฐ€ ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ณด๋‹ค ์กฐ๊ธˆ ๋” ๋ณดํŽธ์ ์ธ ๊ฒฝ์šฐ๊นŒ์ง€ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, Container๋งŒ ๋Œ€์ƒ์œผ๋กœ ํ•˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ๋œ๋‹ค๋ฉด std::begin์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
์œ„์—์„œ Template Specialization์„ ์ฐพ์•„๋ดค๋‹ค๋ฉด, std::begin์ด ํฌ์ธํ„ฐ๋„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ์ด ๋•๋ถ„์ž„์„ ๋ˆˆ์น˜์ฑŒ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

Dependent Type

template <typename C, typename... Arg> void test(C& container, int value, Arg... args) { container = C{args...}; try { typename C::iterator iter = easyfind(container, value); std::cout << "Value " << value << " found on Index " << std::distance(std::begin(container), iter) << std::endl; } catch (std::exception& e) { std::cerr << e.what() << std::endl; } }
๋งˆ์ง€๋ง‰์œผ๋กœ, ๋ชจ๋“  Container๋“ค์€ Iterator๋ฅผ ๊ฐ–๊ณ  ์žˆ์œผ๋ฉฐ ๋‚ด๋ถ€์— ๋ณ„์นญ์œผ๋กœ iterator ๋“ฑ์„ ๊ฐ–๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Container๋ฅผ ์ง€์นญํ•˜๋Š” C์— ๋Œ€ํ•ด C::iterator๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. C๊ฐ€ Container๋กœ ๋“ค์–ด์˜ค์ง€ ์•Š์œผ๋ฉด iterator๊ฐ€ ์—†์„ ํ™•๋ฅ ์ด ๋†’์œผ๋ฉฐ, ์ผ๋ฐ˜ ํƒ€์ž…์— ๋Œ€ํ•ด์„  ๋‚ด๋ถ€์— iterator ๋ณ„์นญ์„ ๊ฐ–๊ณ  ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๊ตฌ๋ฌธ์œผ๋กœ ์ž˜๋ชป ๊ธฐ์žฌ๋œ ์ธ์ž์— ๋Œ€ํ•ด์„œ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฑธ๋Ÿฌ๋‚ผ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.
ํ˜น์—ฌ๋‚˜ ์ง์ ‘ ์ •์˜ํ•œ ํด๋ž˜์Šค์— iterator ๋ณ„์นญ์ด ์กด์žฌํ•œ๋‹ค๋ฉด test ํ•จ์ˆ˜๊ฐ€ ๊ทธ๋Œ€๋กœ ์ด์šฉ๋˜๋Š” ๊ฒƒ ์•„๋‹Œ๊ฐ€ ํ•˜๊ณ  ๊ฑฑ์ •์„ ํ•  ์ˆ˜๋„ ์žˆ๋Š”๋ฐ, ์ •์˜๋œ ํด๋ž˜์Šค๊ฐ€ iterator๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค๋Š” ์ „์ œ๊ฐ€ Container๋กœ์จ ๊ตฌํ˜„๋œ ๊ฒƒ์„ ์˜๋ฏธํ•˜๋ฏ€๋กœ test ํ•จ์ˆ˜๊ฐ€ ์ด์šฉ๋  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•  ๋•Œ ์•„๋ฌด๋Ÿฐ ์˜๋ฏธ ์—†์ด iterator๋ฅผ ์ •์˜ํ–ˆ๋‹ค๋ฉด, ์ด์— ๋Œ€ํ•ด์„  ๋‹ค์‹œ ๊ณ ๋ คํ•ด๋ณผ ํ•„์š”๊ฐ€ ์žˆ๋‹ค.
์ด ๋•Œ ์กฐ๊ธˆ ํŠน์ดํ•œ ๊ตฌ๋ฌธ์ด ์žˆ๋‹ค๋ฉด, C::iterator ์•ž์— typename์ด ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ํ…œํ”Œ๋ฆฟ์„ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•ด template ๊ตฌ๋ฌธ์—์„œ typename์„ ์ด์šฉํ•œ ๊ฒƒ๋„ ์•„๋‹Œ๋ฐ, ์™œ ๋ฉ๊ทธ๋Ÿฌ๋‹ˆ C::iterator ์•ž์— typename์ด ์กด์žฌํ•˜๋Š”์ง€ ์˜์•„ํ•  ์ˆ˜ ์žˆ๋‹ค. Module 07์˜ ๊ธ€์„ ์œ ์‹ฌํžˆ ์ฝ์—ˆ๋‹ค๋ฉด, ํ…œํ”Œ๋ฆฟ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํƒ€์ž…์œผ๋กœ ๋ฐ›๋„๋ก ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ๊ณ , ๊ฐ’์œผ๋กœ ๋ฐ›๋„๋ก ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์„ ๊ฒƒ์ด๋‹ค. ์ฆ‰, C๊ฐ€ ๊ฐ’์ด๋“  ํƒ€์ž…์ด๋“  :: ๋ผ๋Š” Scope ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ๋‚ด๋ถ€ ์š”์†Œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
C์— ::๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋ฉด, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์‚ฌ์ „์— ์ด๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ์•Œ๋ฆด ๊ฒƒ์ด๋‹ค.
C๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” ์š”์†Œ๋“ค์„ ์ž์œ ๋กญ๊ฒŒ ์ด์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋กœ๊ทธ๋ž˜๋จธ์—๊ฒŒ ์ฃผ์–ด์ง€๋Š” ์ž์œ ๋„๋Š” ๋†’์•„์ง€์ง€๋งŒ, ๋ถˆํ–‰ํ•˜๊ฒŒ๋„ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ::๋กœ ์ ‘๊ทผํ•œ ๋‚ด๋ถ€ ์š”์†Œ๊ฐ€ ํƒ€์ž…์ธ์ง€ ๊ฐ’์ธ์ง€ ํŒ๋ณ„ํ•˜์ง€ ๋ชปํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ::๋กœ ๋‚ด๋ถ€ ์š”์†Œ์— ์ ‘๊ทผํ•œ ๊ฒฝ์šฐ ๋ฐ˜๋“œ์‹œ ํƒ€์ž…์ธ์ง€ ๊ฐ’์ธ์ง€ ๊ตฌ๋ถ„ํ•ด์ค˜์•ผ ํ•˜๋Š”๋ฐ, ํƒ€์ž…์ธ ๊ฒฝ์šฐ์—๋Š” typename์„ ๋ช…์‹œ์ ์œผ๋กœ ๊ธฐ์žฌํ•ด์•ผ ํ•œ๋‹ค. ์ด์™€ ๊ฐ™์ด ํ…œํ”Œ๋ฆฟ ์ธ์ž๋ฅผ ::๋กœ ์ด์šฉํ–ˆ์„ ๋•Œ typename์„ ๋ช…์‹œํ•œ ํƒ€์ž…๋“ค์„ Dependent Type (์˜์กด ํƒ€์ž…)์ด๋ผ๊ณ  ํ•œ๋‹ค.
๋งŒ์ผ ์œ„์˜ C::iterator์—์„œ typename์„ ์ œ๊ฑฐํ•˜๊ณ  ์ปดํŒŒ์ผ ํ•ด๋ณด๋ฉด, ์„ค๋ช…ํ•œ๋Œ€๋กœ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” C::iterator๊ฐ€ ๊ฐ’์ธ์ง€ ํƒ€์ž…์ธ์ง€ ์•Œ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— Ambiguity๋กœ ์—๋Ÿฌ๋ฅผ ๋‚ด๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

2. ex01 (Span)


ex01๊ฐ€ Module 08์—์„œ ๊ฐ€์žฅ STL์ด ํ•„์š”ํ•œ ๋ฌธ์ œ๊ฐ€ ์•„๋‹Œ๊ฐ€ ๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. Span ํด๋ž˜์Šค๋Š” ์ƒ์„ฑ์ž์˜ ์ธ์ž๋กœ ๋ฐ›์€ ๊ฐ’๋งŒํผ๋งŒ ๋‚ด๋ถ€ ์š”์†Œ๋ฅผ ๋‘˜ ์ˆ˜ ์žˆ๊ณ , ๋‚ด๋ถ€ ์š”์†Œ์˜ ์ถ”๊ฐ€๋ฅผ addNumber๋ฅผ ํ†ตํ•ด ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค. ํŠนํžˆ shortestSpan๊ณผ longestSpan์„ ์ฐพ์•„๋‚ด๋ ค๋ฉด <algorithm>์˜ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ํŽธํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ง์ ‘ ๋™์  ํ• ๋‹น์„ ๋ฐ›์•„์„œ ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ์‹์œผ๋กœ์˜ ์šด์šฉ๋ณด๋‹ค๋Š” Container๋ฅผ ์ด์šฉํ•˜์—ฌ ์š”์†Œ ์ €์žฅ๊ณผ ๋กœ์ง์—์„œ ๋ชจ๋‘ ๋“์„ ๋ณด๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ์ ์ ˆํ•œ Container๋ฅผ ์ฐพ๊ฒŒ ๋˜๋ฉด, Destructor์™€ Deep Copy๋ฅผ ์‹ ๊ฒฝ ์“ธ ํ•„์š” ์—†์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ (๊ฐ Container ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋กœ ์ •์˜๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ), ์š”์†Œ ์œ ์ง€์™€ addNumber์˜ ๊ตฌํ˜„๋„ ์ƒ๋‹นํžˆ ๊ฐ„๋‹จํ•ด์ง„๋‹ค.
shortestSpan์€ ๋‚ด๋ถ€ ์š”์†Œ์˜ ์ตœ์†Œ ๊ฐ’๊ณผ ๊ทธ ๋‹ค์Œ ์ตœ์†Œ ๊ฐ’๊ณผ์˜ ์ฐจ์ด๋ฅผ ์˜๋ฏธํ•˜๊ณ , longestSpan์€ ๋‚ด๋ถ€ ์š”์†Œ์˜ ์ตœ์†Œ ๊ฐ’๊ณผ ์ตœ๋Œ€ ๊ฐ’์˜ ์ฐจ์ด๋ฅผ ์˜๋ฏธํ•œ๋‹ค.
๋‚ด ๊ฒฝ์šฐ์—๋Š” std::vector<int>๋ฅผ ์ด์šฉํ–ˆ๊ณ , ์ถ”๊ฐ€์ ์ธ index๋ฅผ ์ •์˜ํ•˜์—ฌ ์ด์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค๋Š” std::vector<T>์˜ size ๋ฉค๋ฒ„ ํ•จ์ˆ˜์™€ capacity ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋Š” ์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค. ํŠนํžˆ std::vector<int>๋ฅผ private ์˜์—ญ์œผ๋กœ ๋‘๋ฉด์„œ, std::vector<int>์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก getData ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•ด๋’€๋‹ค.
Span ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ์š”์†Œ๋ฅผ ์ˆ˜์ •ํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ๊ฐ€์ •ํ•˜์—ฌ getData๋Š” const std::vector<int>&๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” const ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋กœ ์ •์˜ํ•ด๋’€๋‹ค. ๋งŒ์ผ ์ˆ˜์ •์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค๋ฉด const๊ฐ€ ๋ชจ๋‘ ๋น ์ง„ getData ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํ•˜๋‚˜ ๋” Overloading ํ•˜๋ฉด ๋œ๋‹ค.
// s -> Span Object // _data -> std::vector<int> Object _data.reserve(s.getData().capacity()); std::copy(std::begin(s.getData()), std::end(s.getData()), std::back_inserter(_data));
์ด ๊ฐ€์šฉ ์š”์†Œ์˜ ์ˆ˜์™€ ํ˜„์žฌ ์š”์†Œ์˜ ์ˆ˜๋ฅผ ๋ณ„๋„์˜ ๋ณ€์ˆ˜๋กœ ๋‘์ง€ ์•Š๊ณ  ์šด์šฉํ–ˆ๋‹ค๊ณ  ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ƒ์„ฑ์ž์™€ operator=์—์„œ๋Š” capacity๋ฅผ ์ด์šฉํ•˜์—ฌ ์ด ๊ฐ€์šฉ ์š”์†Œ์˜ ์ˆ˜๋กœ, size๋ฅผ ์ด์šฉํ•˜์—ฌ ํ˜„์žฌ ์š”์†Œ์˜ ์ˆ˜๋กœ ์ด์šฉ๋˜๋„๋ก ๊ตฌํ˜„ํ–ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ std::vector<int>์˜ ์ƒ์„ฑ์ž๋กœ ๋ฏธ๋ฆฌ size๋ฅผ ํ• ๋‹น ๋ฐ›์•„ ์ด์šฉํ•˜๋Š” ๋ฐฉ์‹ ๋ณด๋‹ค, reserve ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋กœ capacity๋งŒ ๋Š˜๋ฆฌ๊ณ  std::copy๋ฅผ ์ด์šฉํ•  ๋•Œ๋Š” std::back_inserter๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‚ด๋ถ€์ ์œผ๋กœ push_back ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ size๋ฅผ ๋Š˜๋ฆฌ๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ–ˆ๋‹ค.
๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋Š” size์™€ capacity๊ฐ€ 0์ผ ์ˆ˜ ์žˆ๋„๋ก std::vector<int>์— ๋Œ€ํ•ด์„œ reserve(0)๋กœ ํ˜ธ์ถœํ•˜๋„๋ก ๋งŒ๋“ค์—ˆ๊ณ , ์• ์ดˆ์— ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ๋ชปํ•˜๋„๋ก private ์˜์—ญ์œผ๋กœ ๋นผ๋‘์—ˆ๋‹ค. ๋˜ํ•œ std::size_t๋กœ capacity๋ฅผ ์ œ๊ณต ๋ฐ›๋Š” ์ƒ์„ฑ์ž์—์„œ๋Š” std::vector<int>์˜ ์ƒ์„ฑ์ž๋กœ size๋ฅผ ๋Š˜๋ ค์„œ ๋ฏธ๋ฆฌ ํ• ๋‹น์„ ๋ฐ›๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๋‹จ์ˆœํžˆ reserve ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋งŒ ํ˜ธ์ถœํ•˜์—ฌ capacity๋งŒ ๋Š˜๋ ค๋‘์—ˆ๋‹ค.


Span ํด๋ž˜์Šค์—์„œ ์ •์˜ํ•ด์•ผ ํ•˜๋Š” Exception์€ std::vector<int>์˜ capacity๊ฐ€ ๊ฝ‰์ฐจ์„œ ์š”์†Œ ์ถ”๊ฐ€๊ฐ€ ์•ˆ ๋˜๋Š” CannotStoreException๊ณผ ๋‚ด๋ถ€ ์š”์†Œ๊ฐ€ 1๊ฐœ๋งŒ ์กด์žฌํ•ด์„œ Span์„ ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ์˜ CannotSpanException์œผ๋กœ 2๊ฐœ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
addNumber๋ฅผ ์ด์šฉํ•  ๋•Œ CannotStoreException์„ ์ด์šฉํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, std::vector<T>๋Š” ๋‚ด๋ถ€์— ํ• ๋‹น๋œ capacity๊ฐ€ ๋ถ€์กฑํ•˜๋”๋ผ๋„ push_back ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋กœ size๋ฅผ ๋Š˜๋ ค์„œ capacity๋ณด๋‹ค size๊ฐ€ ์ปค์ง€๊ฒŒ ๋˜๋ฉด ์ž๋™์œผ๋กœ capacity๋ฅผ ๋Š˜๋ฆฌ๋„๋ก ๊ตฌํ˜„๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— push_back ๋ฉค๋ฒ„ ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ ์ „์—๋Š” capacity ๋ฉค๋ฒ„ ํ•จ์ˆ˜์™€ size ๋ฉค๋ฒ„ ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ๋กœ ๋‘ ๊ฐ’์„ ๋น„๊ตํ•˜์—ฌ ์ ์ ˆํ•˜๊ฒŒ Exception์„ ๋˜์ง€๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.
shortestSpan๊ณผ longestSpan์€ ๋‚ด๋ถ€ ์š”์†Œ๊ฐ€ 1๊ฐœ์ธ ๊ฒฝ์šฐ์—๋Š” Span์„ ์ฐพ์„ ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์ „์— ๋ฐ˜๋“œ์‹œ size ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์š”์†Œ์˜ ์ˆ˜๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ๊ณผ์ •์ด ํ•„์š”ํ•˜๋‹ค.


longestSpan์˜ ๊ฒฝ์šฐ ๋‚ด๋ถ€ ์š”์†Œ์˜ ์ตœ์†Œ ๊ฐ’๊ณผ ์ตœ๋Œ€ ๊ฐ’๋งŒ ์ฐพ์œผ๋ฉด ๋˜๋ฏ€๋กœ, std::min๊ณผ std::max๋ฅผ ํ•œ ๋ฒˆ์”ฉ ํ˜ธ์ถœํ•ด์„œ ํ’€๋ฉด ๋œ๋‹ค. ์ด ๋•Œ std::minmax_element๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ฉด pair<ForwardIterator, ForwardIterator> ํ˜•ํƒœ๋กœ ์ตœ์†Œ ๊ฐ’์˜ ์œ„์น˜์™€ ์ตœ๋Œ€ ๊ฐ’์˜ ์œ„์น˜๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, pair. first์™€ pair.second๋ฅผ ๊ฐ๊ฐ ์ฐธ์กฐํ•˜์—ฌ ๋บ€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๊ตฌ์„ฑํ•ด๋„ ๋œ๋‹ค. (pair์˜ first์™€ second๊ฐ€ Iterator์ด๋ฏ€๋กœ ์—ญ์ฐธ์กฐํ•˜์—ฌ ๊ฐ’์„ ์–ป์–ด๋‚ด์•ผ ํ•œ๋‹ค.)
std::minmax๋ผ๋Š” ํ•จ์ˆ˜๋„ ์žˆ๋Š”๋ฐ ํ•ด๋‹น ํ•จ์ˆ˜์˜ ์›ํ˜•์„ ๋ณด๋ฉด, std::initializer_list<T> ํ˜น์€ 2๊ฐœ์˜ ์ธ์ž๋งŒ ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์—ฌ๊ธฐ์„œ๋Š” ์ ์ ˆํ•˜์ง€ ์•Š๋‹ค.


๊ฐ€์žฅ ์ž‘์€ 2๊ฐœ ๊ฐ’์„ ์ฐพ๋Š” ์ž˜๋ชป๋œ ํ’€์ด (jeongwle๋‹˜ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค)
์ž์นซ ์œ„์˜ ํ† ๊ธ€์—์„œ ์ œ์‹œํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๊ฐ€์žฅ ์ž‘์€ 2๊ฐœ ๊ฐ’์„ ์ฐพ๋Š” ๊ฒƒ์œผ๋กœ ์˜คํ•ดํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฃผ์˜ํ•˜์ž. ๊ทธ์ € ๊ตฌ๊ฐ„ ๋‚ด์— ์กด์žฌํ•˜๋Š” ์ฐจ์ด๊ฐ€ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์„ ์ฐพ์•„๋‚ด๋ฉด ๋œ๋‹ค. ์ด๋ฒˆ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ std::adjacent_difference๋ฅผ ํ™œ์šฉํ•  ๊ฒƒ์ด๋‹ค.
std::vector<int> diff(_data); std::adjacent_difference(std::begin(diff), std::end(diff), std::begin(diff)); std::transform(std::begin(diff), std::end(diff), std::begin(diff), [] (int& i) { return std::abs(i); }); return ((*std::min_element(std::begin(diff), std::end(diff))));
์œ„ ์ฝ”๋“œ์™€ ๊ฐ™์ด ๊ธฐ์กด ์š”์†Œ๋“ค์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณต์‚ฌ ์ƒ์„ฑ์ž๋กœ std::vector<int>๋ฅผ ์ƒ์„ฑํ•œ ํ›„, ์ธ์ ‘ํ•œ ์š”์†Œ๋“ค ๊ฐ„์˜ ์ฐจ์ด๋ฅผ ๊ตฌํ•˜๋Š” std::adjacent_difference๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ํ•ด๋‹น ํ•จ์ˆ˜๋Š” <numeric>์— ์กด์žฌํ•˜๋ฉฐ, ์ฒซ ๋ฒˆ์งธ์™€ ๋‘ ๋ฒˆ์งธ ๊ตฌ๊ฐ„ ์‚ฌ์ด์˜ ๊ฐ ์ธ์ ‘ ์š”์†Œ ๊ฐ„ ์ฐจ์ด๋ฅผ ๊ตฌํ•  ๋•Œ ์„ธ ๋ฒˆ์งธ ์ธ์ž์—์„œ๋ถ€ํ„ฐ ๊ธฐ๋กํ•˜๊ฒŒ ๋œ๋‹ค. ์ฐจ์ด ์ž์ฒด๋Š” ์–‘์ˆ˜์ผ ์ˆ˜๋„ ์žˆ๊ณ  ์Œ์ˆ˜์ผ ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, std::transform์„ ํ˜ธ์ถœํ•˜์—ฌ ์ฐจ์ด ๊ฐ’์„ ์œ ์ง€ํ•˜๊ณ  ์žˆ๋Š” diff์˜ ์š”์†Œ๋ฅผ ์ ˆ๋Œ€ ๊ฐ’์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ๋ฉด ๋œ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์„ ์ฐพ์•„์•ผํ•˜๋ฏ€๋กœ std::min_element๋กœ ์œ„์น˜๋ฅผ ์ฐพ์€ ํ›„, ์—ญ์ฐธ์กฐํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋œ๋‹ค.
์ฐธ๊ณ ๋กœ ํŽธ์˜์„ฑ ๋•Œ๋ฌธ์— ์œ„์˜ Callable์€ Lambda๋กœ ์ž‘์„ฑ๋˜์–ด ์žˆ์ง€๋งŒ, ์„œ๋ธŒ์ ํŠธ์—์„œ๋Š” C++98์„ ์ง€์ผœ์•ผํ•˜๋ฏ€๋กœ ์ด๋ฅผ ์‚ฌ์šฉํ•ด์„  ์•ˆ ๋œ๋‹ค. Lambda์˜ ๋ชจ์ฒด์ธ Functor๋ฅผ ์ฐพ์•„์„œ ๊ตฌํ˜„ํ•ด๋ณด์ž.


๋ฌธ์ œ๋ฅผ ์ž˜ ์ฝ์–ด๋ณด๋ฉด ์š”๊ตฌ ์‚ฌํ•ญ์€ ์•„๋‹ˆ์ง€๋งŒ, Iterator๋ฅผ ํ™œ์šฉํ•˜์—ฌ Range๋กœ ๋‚ด๋ถ€ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋‘๋ฉด ๋” ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค๊ณ  ํ–ˆ๋‹ค. ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ๋„ ์•Œ์•„๋ณด์ž.
๊ธฐ๋ณธ์ ์œผ๋กœ Range-Based๋Š” Container์˜ Iterator์™€ ๋ฐฐ์—ด์˜ ํฌ์ธํ„ฐ์— ๋Œ€ํ•ด์„œ๋„ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์ฆ‰, Span ํด๋ž˜์Šค์˜ addRange๋ผ๋Š” ํ•จ์ˆ˜๋Š” ์ž„์˜์˜ Container์— ๋Œ€ํ•ด์„œ๋„ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋ฏ€๋กœ, ํ•จ์ˆ˜ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์ •์˜๋˜์–ด์•ผ ํ•œ๋‹ค. ์ด ๋•Œ Iterator๋„ ๋ฐ›์„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๊ณ , ํฌ์ธํ„ฐ๋„ ๋ฐ›์„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋ฏ€๋กœ ์–ด๋–ป๊ฒŒ typename์„ ์ •์˜ํ•˜๋ฉด ์ข‹์„์ง€ ๊ณ ๋ฏผ์ด ๋  ๊ฒƒ์ธ๋ฐ, ๋‚ด๋ถ€์—์„œ ์ˆœ์ˆ˜ํ•˜๊ฒŒ ๋กœ์ง์„ ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋ฉด ์ด๊ฒƒ์ด ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์ง€๋งŒ STL์˜ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์‹์œผ๋กœ Wrapping ํ•˜๋ฉด ํฌ๊ฒŒ ๋ฌธ์ œ ๋  ๊ฒƒ์ด ์—†๋‹ค.
std::vector<T>์™€ std::deque<T>๋Š” Random Access Iterator๋ฅผ ์ด์šฉํ•˜๋„๋ก ๊ตฌํ˜„๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ํฌ์ธํ„ฐ์™€ ๋™์ผํ•œ ์„ฑ์งˆ์„ ๊ฐ–๋Š”๋‹ค. ๋”ฐ๋ผ์„œ ์ˆœ์ˆ˜ํ•˜๊ฒŒ ๋กœ์ง์„ ์ง์ ‘ ๊ตฌํ˜„ํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค. ํ•˜์ง€๋งŒ std::list<T>๋Š” Bidirectional Iterator๋ฅผ ์ด์šฉํ•˜๋„๋ก ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š”๋ฐ, ์ด๋Š” ํฌ์ธํ„ฐ์˜ ์‚ฌ์น™ ์—ฐ์‚ฐ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ STL์„ ์ด์šฉํ•˜์ง€ ์•Š๊ณ  ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค.
if (std::distance(begin, end) > static_cast<long>(_data.capacity() - _data.size())) throw (CannotStoreException());
Range-Based๋กœ ๋‚ด๋ถ€ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ, ํ˜„์žฌ capacity์™€ size์˜ ์ฐจ์ด๊ฐ€ ๊ฐ Iterator์˜ ์ฐจ์ด๋ณด๋‹ค ์ž‘๋‹ค๋ฉด ํ•จ์ˆ˜๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ Exception์„ ๋˜์ ธ์•ผ ํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ ์ฐจ์ด๋ฅผ ๊ตฌํ•˜๋Š” ๋ถ€๋ถ„์ด ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด๊ณ , ํŠน์ • Container์˜ Iterator๋Š” ์ฐจ์ด๋ฅผ ๊ตฌํ•˜๋Š” operator-๊ฐ€ ์ง€์›๋˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ๋ฌธ์ œ์˜ ์›์ธ์ด๋‹ค. ์ด๋ฅผ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•ด์„  std::distance๋ฅผ ์ด์šฉํ•˜๋ฉด ๋˜๋Š”๋ฐ, std::distance๋Š” <algorithm>์—์„œ ์ œ๊ณต๋˜๊ธฐ ๋•Œ๋ฌธ์— ํฌ์ธํ„ฐ์— ๋Œ€ํ•ด์„œ๋„ ๋™์ž‘ํ•˜๊ณ  Iterator์— ๋Œ€ํ•ด์„œ๋„ ๋™์ž‘ํ•˜๋ฉฐ, ๋‘ ์ธ์ž์˜ ์ฐจ์ด ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค.
๋‘ ์ฐจ์ด ๊ฐ’์˜ ๋น„๊ต๊ฐ€ ๋๋‚˜๊ณ  ๋‚ด๋ถ€ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•œ ์ƒํ™ฉ์ด๋ผ๋ฉด, Container๋“ค์˜ Iterator๋Š” ++, --, *์„ ์ง€์›ํ•˜๋ฏ€๋กœ std::vector<int>์— push_back ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ ๋‚ด๋ถ€ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋„๋ก ์ž‘์„ฑํ–ˆ๋‹ค.
std::stack<T>, std::queue<T>, std::priority_queue<T>๋Š” Adaptor Container๋กœ Iterator๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ addRange ํ›„๋ณด๋กœ ์ ์ ˆํ•˜์ง€ ์•Š์•„ ์ธ์ž๋กœ ๋“ค์–ด์˜ค์ง€ ์•Š๋Š” ๊ฒƒ์„ ์ „์ œ๋กœ ๋’€๋‹ค.

3. ex02 (Mutated abomination)

Adaptor Container

ex01์˜ ๋งˆ์ง€๋ง‰ ๋ถ€๋ถ„์— std::stack<T>, std::queue<T>, std::priority_queue<T>๋ฅผ ์–ธ๊ธ‰ํ•˜๋ฉด์„œ Adaptor Container๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์šฐ์„  Container๋“ค์˜ ๋ถ„๋ฅ˜๋Š” ํŠน์„ฑ์— ๋”ฐ๋ผ ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚˜๋‰œ๋‹ค.
Sequential Container
โ†’ std::vector<T>, std::deque<T>, std::list<T>, std::forward_list<T>
Adaptor Container
โ†’ std::stack<T>, std::queue<T>, std::priority_queue<T>
Associative Container
โ†’ std::map<T>, std::multimap<T>, std::set<T>, std::multiset<T>
Unordered Associative Container
โ†’ std::unordered_map<T>, std::unordered_multimap<T>, std::unordered_set<T>, std::unordered_multiset<T>
์ž˜ ์ƒ๊ฐํ•ด๋ณด๋ฉด Adaptor Container์— ๋ช…์‹œ๋œ 3๊ฐœ์˜ Container๋Š” ์„ ํ˜•์ ์ธ ํŠน์„ฑ์„ ๊ฐ–๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ๋– ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๋Š”๋ฐ, ์™œ Sequential Container๊ฐ€ ์•„๋‹Œ์ง€ ์˜์•„ํ•  ๊ฒƒ์ด๋‹ค. ์ด๋“ค์€ ์„ ํ˜•์ ์ธ ํŠน์„ฑ์„ ๊ฐ–๊ณ ๋Š” ์žˆ์ง€๋งŒ ํŠน์ • ๋ชฉ์ ์— ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ •์˜๋˜์—ˆ๊ณ , ์ด์— ๋”ฐ๋ผ ์„ ํ˜•์ ์ธ ํŠน์„ฑ์„ ๊ฐ–๊ณ  ์žˆ๋Š” Sequential Container๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค. ์ด๋“ค์˜ ๊ณตํ†ต์ ์ธ ํŠน์„ฑ์œผ๋กœ๋Š” Iterator๋ฅผ ๊ฐ–๊ณ  ์žˆ์ง€ ์•Š์•„, ์ˆœํšŒ, ํƒ์ƒ‰, ๋“ฑ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ , ๊ฐ Container์˜ ํŠน์„ฑ์— ๋งž๊ฒŒ ํ•œ ๋ฒˆ์— ํ•œ ์š”์†Œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
๊ธฐ๋ฐ˜์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค๋Š” ๊ฒƒ์ด ๊ณง ์ƒ์†์„ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค. ์„ ํƒ๋œ Sequential Container๋ฅผ ์ ์ ˆํžˆ ์บก์Šํ™”ํ•˜์—ฌ ๋‚ด๋ถ€ ๋กœ์ง์„ ๊ฐ€๊ณตํ•ด์„œ Adaptor Container๋กœ ์ œ๊ณต๋œ๋‹ค.
std::stack<T>์€ ํ…œํ”Œ๋ฆฟ ์ธ์ž๋กœ ํƒ€์ž…์„ ๋ช…์‹œํ•˜๋ฉด, ์„ ํƒ์ ์œผ๋กœ ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ ์–ด๋–ค Sequential Container๋ฅผ ์ด์šฉํ•˜์—ฌ std::stack<T>์„ ์ƒ์„ฑํ•  ๊ฒƒ์ธ์ง€ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. std::stack<T>์— ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” Sequential Container๋Š” std::vector<T>, std::list<T>, std::deque<T>์ด๋ฉฐ, ๋ณ„๋„๋กœ ๋ช…์‹œํ•˜์ง€ ์•Š์œผ๋ฉด ํ…œํ”Œ๋ฆฟ ๊ธฐ๋ณธ ์ธ์ž์— ๋”ฐ๋ผ std::deque<T>๋ฅผ ์ด์šฉํ•œ๋‹ค.
์ด์™€ ๊ฐ™์€ ํŠน์„ฑ์€ std::queue<T>์™€ std::priority_queue<T>๋„ ๋™์ผํ•˜๋‹ค. std::queue๋Š” std::list<T>์™€ std::deque<T>๋ฅผ ์ด์šฉํ•˜์—ฌ ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ธฐ๋ณธ ์„ค์ •์€ std::deque<T>์ด๋‹ค. std::priority_queue<T>๋Š” std::vector<T>์™€ std::deque<T>๋ฅผ ์ด์šฉํ•˜์—ฌ ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ธฐ๋ณธ ์„ค์ •์€ std::deque<T>์ด๋‹ค.
์ด์ œ ex02๊ฐ€ ์š”๊ตฌํ•˜๋Š” ๋ฐ”๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๊ฐ์ด ์˜ฌ ๊ฒƒ์ด๋‹ค. std::stack<T>๋Š” Adaptor Container์ด๋ฏ€๋กœ Iterator๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, Iterator๋ฅผ ์ ์ ˆํžˆ ์ถ”๊ฐ€ํ•˜์—ฌ ์ˆœํšŒ ๋ฐ ํƒ์ƒ‰์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค.
์ผ๋ฐ˜์ ์œผ๋กœ ์ด์ฒ˜๋Ÿผ ์ˆœํšŒ ๋ฐ ํƒ์ƒ‰์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” std::stack<T>๋ฅผ ์ด์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋งŒ์ผ ์ˆœํšŒ ๋ฐ ํƒ์ƒ‰์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋ผ๋ฉด ๋‹ค๋ฅธ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹์€ ์„ ํƒ์ด๋ฏ€๋กœ, ์šฉ๋„์— ๋งž๋Š” ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ๊ณ ๋ฏผํ•˜๋Š” ์Šต๊ด€์€ ๊ต‰์žฅํžˆ ์ค‘์š”ํ•˜๋‹ค. ๋˜ํ•œ ๋ถ„๋ช… Adaptor Container๊ฐ€ ์—†์–ด๋„ Sequential Container ๋งŒ์œผ๋กœ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ํ•  ์ˆ˜ ์žˆ์Œ์—๋„ Adaptor Container๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒƒ์€, ์˜๋ฏธ ์ƒ ๋” ์ ์ ˆํ•œ ํ˜•ํƒœ์˜ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.

Kinds of Iterators & Alias

C++11 ์ด์ „์—๋„ Container๋ผ๋Š” ๊ฐœ๋…์€ ์กด์žฌํ–ˆ์—ˆ๋Š”๋ฐ, C++11์ด ์˜ค๋ฉด์„œ ์—ฌ๋Ÿฌ Container๋“ค์„ ๋ฌถ์–ด STL๋กœ ์ทจ๊ธ‰๋˜์—ˆ๊ณ  ์ด์— ๋”ฐ๋ผ ๊ธฐ์กด Container์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ณด๋‹ค ๋” ๋งŽ์€ ๊ธฐ๋Šฅ๋“ค์ด ์ถ”๊ฐ€ ๋˜์—ˆ๋‹ค. ํŠนํžˆ ์ด๋ฒˆ ๋ฌธ์ œ์ฒ˜๋Ÿผ Iterator๋ฅผ ์ด์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ C++98์—์„œ๋Š” begin๊ณผ end ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋งŒ ์กด์žฌ ํ–ˆ๋‹ค๋ฉด, C++11์—์„œ๋Š” cbegin๊ณผ cend, rbegin๊ณผ rend, crbegin๊ณผ crend๊ฐ€ ์ถ”๊ฐ€ ๋˜์—ˆ๋‹ค. C++11์˜ ํŽธ๋ฆฌํ•œ ๊ธฐ๋Šฅ๋“ค์„ Module 08์—์„œ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•ด์คฌ์œผ๋ฏ€๋กœ ์ด๋“ค์„ ๊ตฌํ˜„ํ•ด์ค„ ํ•„์š”๊ฐ€ ์žˆ์ง€ ์•Š์€๊ฐ€?
์œ„์—์„œ ๋ถ„๋ฅ˜๋œ Container๋“ค์€ ๋‚ด๋ถ€์— ์—ฌ๋Ÿฌ Iterator๊ฐ€ (์กฐ๊ธˆ์€ ๋ณต์žกํ•œ ๊ตฌ์กฐ๋กœ) ์ •์˜๋˜์–ด ์žˆ๊ณ , ๊ทธ ์ข…๋ฅ˜๋Š” iterator, const_iterator, reverse_iterator, const_reverse_iterator๋กœ ๋‚˜๋‰œ๋‹ค. iterator๋ฅผ ์ด์šฉํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ begin๊ณผ end, const_iterator๋ฅผ ์ด์šฉํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ cbegin๊ณผ cend, reverse_iterator๋ฅผ ์ด์šฉํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ rbegin๊ณผ rend, const_reverse_iterator๋ฅผ ์ด์šฉํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ crbegin, crend๊ฐ€ ๋œ๋‹ค.
๊ธฐ๋ณธ์ ์œผ๋กœ Iterator๋Š” ์ƒ์† ๊ตฌ์กฐ์— ๋”ฐ๋ผ InputIterator, OutputIterator, ForwardIterator, BidirectionalIterator, RandomAccessIterator๋กœ ๋‚˜๋‰˜๊ณ , ๊ฐ๊ฐ์˜ ์นดํ…Œ๊ณ ๋ฆฌ ํƒœ๊ทธ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Sequential Container์™€ Adaptor Container์˜ ๊ด€๊ณ„์ฒ˜๋Ÿผ Iterator ์—ญ์‹œ Adaptor Iterator๊ฐ€ ์กด์žฌํ•œ๋‹ค. ์ œ์‹œ๋œ 5๊ฐœ์˜ Iterator๋“ค์„ ์ ์ ˆํžˆ ๊ฐ€๊ณตํ•˜์—ฌ ์—ญ๋ฐฉํ–ฅ์œผ๋กœ ์ ‘๊ทผํ•˜๋Š” reverse_iterator, ์š”์†Œ ์ˆ˜์ •์„ ๋ง‰๋Š” const_iterator, ๊ทธ๋ฆฌ๊ณ  ๋‘ ์†์„ฑ์„ ๋ชจ๋‘ ๊ฐ€์ง„ const_reverse_iterator๋ฅผ ๋งŒ๋“ค์–ด ๋‚ผ ์ˆ˜ ์žˆ๋‹ค.
Iterator์˜ const ์†์„ฑ ์ ์šฉ์€ ์‹œ์ž‘ ์ง€์ ๊ณผ ๋ ์ง์˜ ์˜ํ–ฅ ์—†์ด ํ•ด๋‹น ์ง€์ ์˜ ์š”์†Œ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์—†๋Š”์ง€๋งŒ ๊ฒฐ์ •๋œ๋‹ค. ํ•˜์ง€๋งŒ Iterator์˜ reserve ์†์„ฑ์€ ์ ์šฉ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ์‹œ์ž‘ ์ง€์ ๊ณผ ๋ ์ง€์ ์„ ์˜๋ฏธํ•˜๋Š” begin๊ณผ end์˜ ์ฐธ์กฐ ์ง€์ ์ด ๋‹ฌ๋ผ์ง„๋‹ค. ๋”ฐ๋ผ์„œ Iterator์— ๋Œ€ํ•ด ์ •ํ™•ํžˆ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•œ๋ฐ, ์ด์— ๋Œ€ํ•ด์„  ์•„๋ž˜ ๋งํฌ์˜ ์ œ 39์žฅ ๋ฐ˜๋ณต์ž ๋ถ€๋ถ„์œผ๋กœ ๊ผผ๊ผผํžˆ ํ•™์Šตํ•˜์ž. ์ œ์ผ ์ค‘์š”ํ•œ ๊ฒƒ์€ end๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์ง€์ ์ด ๋‚ด๋ถ€ ์š”์†Œ์˜ ๋ ์ง€์ ์ด ์•„๋‹ˆ๋ผ ๋์—์„œ 1์นธ ๋” ์ด๋™ํ•œ ์ง€์ ์ž„์„ ๋ช…์‹ฌํ•˜์ž.
์ƒ์†ํ•œ std::stack<T>๋Š” Iterator๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์•„์„œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ์ง€ ๋ง‰๋ง‰ํ•˜๊ฒ ์ง€๋งŒ, ๊ฐ Iterator์— ํ•ด๋‹นํ•˜๋Š” ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๋งŒ๋“ค์–ด ๋‚ด๋Š” ๋ฐฉ๋ฒ•์€ ๊ฐ„๋‹จํ•˜๋‹ค. std::stack<T>๊ฐ€ Adaptor Container๋ผ๋Š” ์ ์„ ๋ช…์‹ฌํ•˜๋ฉด, std::stack<T>๋ฅผ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉ๋œ Container ํƒ€์ž…์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ง์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‚ด ๊ฒฝ์šฐ์—” ๊ธฐ๋ณธ ์„ค์ •์„ ์ด์šฉํ•˜๋Š” std::stack<T>๋ฅผ ์ƒ์†๋ฐ›๋„๋ก ๋’€๊ธฐ ๋•Œ๋ฌธ์— std::deque<T> ํƒ€์ž…์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. std::stack<T>์˜ ์ •์˜๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด container_type์ด๋ผ๋Š” ๋ณ„์นญ์ด ์กด์žฌํ•˜๋Š”๋ฐ, ์ด ํƒ€์ž… ์ •์˜๋ฅผ ์ด์šฉํ•˜๋ฉด std::deque<T>๋ฅผ ํƒ€์ž…์œผ๋กœ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ std::stack<T>์˜ container_type์œผ๋กœ ๋œ ๊ฐ์ฒด๋Š” c๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ๋„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•ด๋‹น ๊ฐ์ฒด๋Š” protected ์˜์—ญ์— ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ง€๊ธˆ์ฒ˜๋Ÿผ ํŒŒ์ƒ ํด๋ž˜์Šค๋กœ ๋งŒ๋“  MutantStack์—์„œ๋„ std::deque<T> ๊ฐ์ฒด๋ฅผ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
iterator begin(void) { return (this->c.begin()); } iterator end(void) { return (this->c.end()); } const_iterator cbegin(void) const { return (this->c.cbegin()); } const_iterator cend(void) const { return (this->c.cend()); } reverse_iterator rbegin(void) { return (this->c.rbegin()); } reverse_iterator rend(void) { return (this->c.rend()); } const_reverse_iterator crbegin(void) const { return (this->c.crbegin()); } const_reverse_iterator crend(void) const { return (this->c.crend()); }
๋”ฐ๋ผ์„œ ๊ฐ iterator๋ฅผ ์ด์šฉํ•œ begin๊ณผ end๋Š” ์œ„์™€ ๊ฐ™์ด ๊ฐ„๋‹จํžˆ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์œ„์ฒ˜๋Ÿผ ๋‹จ์ˆœํžˆ iterator, const_iterator, reverse_iterator, const_reverse_iterator๋ฅผ ์ด์šฉํ•˜๋ ค๊ณ  ํ•˜๋ฉด, MutantStack<T>์—์„œ๋Š” ํ•ด๋‹น ํƒ€์ž…๋“ค์ด ๋ฌด์—‡์ธ์ง€ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„์˜ ๋ณ„์นญ ์ •์˜๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
๋ณ„์นญ ์ •์˜๋ฅผ ํ•  ๋•Œ๋Š” typedef์™€ using์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, typedef๊ฐ€ using๊ณผ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ์ ์–ด๋„ ๋ณ„์นญ ์ •์˜์— ๋Œ€ํ•ด์„  typedef์™€ using์€ ๋™์ผํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์ •์˜๋˜์–ด ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด์™• ์ด์šฉํ•  ๊ฒƒ์ด๋ผ๋ฉด using์„ ์ข€ ๋” ์• ์šฉํ•˜๋Š” ์Šต๊ด€์„ ๋“ค์ผ ์ˆ˜ ์žˆ๋„๋กํ•˜์ž. ์ด์— ๋Œ€ํ•ด์„  ์•„๋ž˜ ๋งํฌ์—์„œ ์ฐจ์ด์ ๊ณผ ๊ทธ ์ด์œ ์— ๋Œ€ํ•ด์„œ ์ž˜ ์„ค๋ช…๋˜์–ด ์žˆ์œผ๋‹ˆ ์ด๋ฅผ ์ฐธ๊ณ ํ•˜๋ฉด ๋œ๋‹ค.
๋‚ด๋ถ€์ ์œผ๋กœ ๋ณ„์นญ ์ •์˜์— ๋Œ€ํ•ด์„  typedef์™€ using์€ ๋กœ์ง์ด ๋™์ผํ•˜๊ฒŒ ๊ตฌํ˜„๋˜์–ด ์žˆ๋‹ค.
std::stack<T>์˜ ์ •์˜๋ฅผ ํ™•์ธํ•˜๋ฉด์„œ ์—ฌ๋Ÿฌ ์ž‘์—…๋“ค์„ ํ•  ์ˆ˜ ์žˆ์—ˆ๋“ฏ์ด, ๋ณ„์นญ ์ •์˜๋Š” ์ง์ ‘ ์ฐพ์•„์„œ ํ•ด๋ณด๋„๋ก ํ•˜์ž. ๋‹จ, ์ฃผ์˜ํ•  ์ ์ด ์žˆ๋‹ค๋ฉด ์œ„์—์„œ ๋ฐฐ์› ๋˜ ์˜์กด ํƒ€์ž…์— ๋Œ€ํ•ด์„œ typename์„ ๋ฐ˜๋“œ์‹œ ๊ธฐ๋กํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์ž.

4. Code of Jseo