/////
Search
moon
sun
๐Ÿ—๏ธ

ft_containers

subject

subject.pdf

๊ณผ์ œ ๋ชฉํ‘œ

STL์— ์žˆ๋Š” ์ปจํ…Œ์ด๋„ˆ ๋งŒ๋“ค๊ธฐ

๋กœ๋“œ๋งต

{ 1phase / container ์˜ ํ•„์ˆ˜ ์š”์†Œ ๊ฐ์žก๊ธฐ but ์ด๋‹จ๊ณ„์—์„  ๋‚ด๊ฐ€ ๋ญ˜ ๋งŒ๋“œ๋Š”์ง€ ๋ชจ๋ฅด๋Š”๊ฒŒ ๋‹น์—ฐ } // ๊ถŒ์žฅ ํ•™์Šต ๊ธฐ๊ฐ„ 2~3์ผ 0. ์‚ฌ์ „ ์ง€์‹ ๊ณต๋ถ€ - SFINAE์™€ enable_if, allocator, is_integral, iterator traits ๋“ฑ 1. // type traits - enable_if, is_integral ๋“ค ๊ตฌํ˜„ 2. iterator traits 3. algorithm - equal, lexicographical_compare 4. pair { 2phase / ์œ„์—์„œ ๋งŒ๋“ ๊ฑธ ์จ๋จน์œผ๋ฉด์„œ ์ดํ•ด๋„ ๋†’์ด๊ธฐ } // ๊ถŒ์žฅ ํ•™์Šต ๊ธฐ๊ฐ„ 2์ผ 5. random access iterator 6. reverse iterator { 3phase / ์œ„์—์„œ ๋งŒ๋“ ๊ฑธ ์‚ฌ์šฉํ•˜๋ฉด์„œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ } // ๊ถŒ์žฅ ํ•™์Šต ๊ธฐ๊ฐ„ 3์ผ 7. vector ๊ตฌํ˜„ 8. vector ๊ตฌํ˜„ ์ดํ›„ adaptor container ๋กœ stack ๊ตฌํ˜„ { 4phase / map์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•˜๊ณ  tree๋ฅผ ๊ตฌํ˜„ํ•  ์ค€๋น„ } // ๊ถŒ์žฅ ํ•™์Šต ๊ธฐ๊ฐ„ 2์ผ 9. tree node 10. tree iterator { 5phase / map ๊ตฌํ˜„ } // ๊ถŒ์žฅ ํ•™์Šต ๊ธฐ๊ฐ„ 3์ผ 11. map -> set (์ธํ„ฐํŽ˜์ด์Šค๋งŒ ๊ตฌํ˜„) 12. red black tree ์ด๋‚˜ avl tree ๋กœ์ง์„ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋ฆฌ ๊ตฌํ˜„ (๋‚ด๋ถ€๋กœ์ง ๊ตฌํ˜„) /* ์ฐธ๊ณ ์‚ฌํ•ญ - ๋Œ€๋ถ€๋ถ„ ๊ตฌํ˜„ํ•ด์•ผํ•  ๊ฒƒ๋“ค์€ cppreference.com ์ด๋‚˜ cplusplus.com ์—์„œ ํ™•์ธ ๊ฐ€๋Šฅ */
Plain Text
๋ณต์‚ฌ
C++์€ ์ œ๋„ˆ๋ฆญํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์œ„ํ•ด template์„ ์ง€์›ํ•œ๋‹ค. template์ด๋ž€ ํ•จ์ˆ˜๋‚˜ ํด๋ž˜์Šค๋ฅผ ๋‹ค์–‘ํ•œ ์ž๋ฃŒํ˜•์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“  ํ‹€์ด๋‹ค. ๋˜ํ•œ ์ด๋Ÿฐ template์„ ์ด์šฉํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ Standard Template Library๋ผ๊ณ  ํ•œ๋‹ค.
โ€ข
์ž„์˜ ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ๋Š” ์ปจํ…Œ์ด๋„ˆ (container)
โ€ข
์ปจํ…Œ์ด๋„ˆ์— ๋ณด๊ด€๋œ ์›์†Œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ˜๋ณต์ž (iterator)
โ€ข
๋ฐ˜๋ณต์ž๋“ค์„ ๊ฐ€์ง€๊ณ  ์ผ๋ จ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ (algorithm)
STL์€ ๋ณดํ†ต ์ด ์„ธ ๊ฐœ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.
์ด STL์˜ container๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์ด ๊ณผ์ œ์˜ ์ฃผ์ œ์ด๊ณ , ์ด๋ฅผ ์œ„ํ•ด ํ•„์š”ํ•œ iterator์™€ algorithm๋“ฑ์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.
์‚ฌ์ „ ์ง€์‹์ธ enable_if, SFINAE๋ฅผ ๊ณต๋ถ€ํ•˜๋ ค๊ณ  ๊ฒ€์ƒ‰ํ–ˆ์„ ๋•Œ ๋‚˜์˜ค๋Š” ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ์ด๋‹ค.
struct T { enum { int_t, float_t } type; template <typename Integer, std::enable_if_t<std::is_integral<Integer>::value, bool> = true > T(Integer) : type(int_t) {} template <typename Floating, std::enable_if_t<std::is_floating_point<Floating>::value, bool> = true > T(Floating) : type(float_t) {} // OK };
C++
๋ณต์‚ฌ
๋ฉ˜ํƒˆ ๋ฐ”์‚ฌ์‚ญโ€ฆ ๋„๋Œ€์ฒด ๋ญ”์†Œ๋ฆฐ์ง€ ํ•˜๋‚˜๋„ ๋ชจ๋ฅด๊ฒ ๋‹ค.
์šฐ์„  enable_if ์™€ is_integral์€ c++ 11 ๋ฒ„์ „์˜ ๊ธฐ๋Šฅ์ด์ง€๋งŒ, ๊ณผ์ œ์—์„œ๋Š” ๊ตฌํ˜„ํ•˜๋ผ๊ณ  ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์šฐ์„  ์ฐพ์•„๋ณด์ž.
์šฐ์„  SFINAE๋Š” ๋งํฌ ๋กœ ๋Œ€์ถฉ ๊ฐœ๋…๋งŒ ๊ฐ์„ ์žก์•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, value_type์ด๋ผ๋Š” ๋ฉค๋ฒ„ํƒ€์ž…์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํด๋ž˜์Šค๊ฐ€ ์ž…๋ ฅ๋˜์–ด์•ผ ํ•˜๋Š” ํ…œํ”Œ๋ฆฟ์—์„œ, int ๋“ฑ์˜ ์ž๋ฃŒํ˜•์ด ๋“ค์–ด์™”์„ ๋•Œ ์˜ค๋ฅ˜๋ฅผ ๋ฑ‰์–ด๋‚ด๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ทธ๋ƒฅ ์˜ค๋ฒ„๋กœ๋”ฉ ํ›„๋ณด์—์„œ ์ œ์™ธ์‹œํ‚ค๋Š” ๊ฒƒ์ด๋‹ค.
๋ฌผ๋ก  int๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๊ฐ€ ์•„์˜ˆ ์—†์œผ๋ฉด ๋‹น์—ฐํžˆ no matching error๊ฐ€ ๋‚˜์ง€๋งŒ, ์—ฌ๊ธฐ์„œ ์˜ค๋ฅ˜๊ฐ€ ์•„๋‹ˆ๋ผ๋Š” ๋œป์€ โ€˜์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ปดํŒŒ์ผ ๊ณผ์ •์—์„œ template ํ•จ์ˆ˜๋ฅผ ํ™•์ธํ•˜๋Š” ๊ณผ์ •์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋‚˜์ง€ ์•Š๋Š”๋‹ค' ๋Š” ๊ฒƒ์ด๋‹ค.
#include <iostream> int negate(int i) { std::cout << "int" << std::endl; return -i; } template <typename T> typename T::value_type negate(const T& t) { std::cout << "SFINAE" << std::endl; return -T(t); } int main() { negate('c'); }
C++
๋ณต์‚ฌ
์œ„์˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด, ์ถœ๋ ฅ์€ int ๊ฐ€ ๋‚˜์˜ค๊ฒŒ ๋œ๋‹ค. char ์ž๋ฃŒํ˜•์ธ c ๊ฐ€ ํ•จ์ˆ˜์— ์ ์šฉ๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ, value_type์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— typename T::value_type negate(const T& t) ํ…œํ”Œ๋ฆฟ์—๋Š” ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค. ํ•˜์ง€๋งŒ SFINAE๋กœ ์ธํ•ด ์˜ค๋ฅ˜๊ฐ€ ๋‚˜์ง€ ์•Š๊ณ  ์˜ค๋ฒ„๋กœ๋”ฉ ํ›„๋ณด์—์„œ ์ œ์™ธ๋˜์–ด char ์ž๋ฃŒํ˜•์ด int ์ž๋ฃŒํ˜•์œผ๋กœ ๋ณ€ํ™˜๋˜์–ด int negate(int i) ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค.
ํ•˜์ง€๋งŒ ์œ„์˜ template ํ•จ์ˆ˜๋ฅผ ์•„๋ž˜ ์ฝ”๋“œ๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ์‹คํ–‰ํ•˜๋ฉด ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
#include <iostream> int negate(int i) { std::cout << "int " << std::endl; return -i; } template <typename T> void negate(const T& t) { typename T::value_type n = -t(); } int main() { negate('c'); }
C++
๋ณต์‚ฌ
์ด ์ฝ”๋“œ๋Š” ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ error: type 'char' cannot be used prior to '::' because it has no members ์—๋Ÿฌ๋ฅผ ๋ฑ‰๋Š”๋‹ค. char ์ž๋ฃŒํ˜•์—๋Š” ๋ฉค๋ฒ„๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— :: ์„ ํ†ตํ•œ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์ด์•ผ๊ธฐ์ด๋‹ค. ์ฆ‰, ์ปดํŒŒ์ผ๋‹จ๊ณ„์—์„œ template ํ•จ์ˆ˜์— char ๋ฅผ ๋„ฃ์–ด๋ณด๋Š” ๊ณผ์ •์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ์ด๋‹ค. ์ด ๊ฒฝ์šฐ๋Š” SFINAE๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š์€ ๊ฒƒ์ด๋‹ค.
์™œ๋ƒํ•˜๋ฉดย T::value_type๋Š” ํ•จ์ˆ˜ ํƒ€์ž…๊ณผ ํ…œํ”Œ๋ฆฟ ํƒ€์ž… ์ธ์ž์˜ ์ฆ‰๊ฐ์ ์ธ ๋งฅ๋ฝ(immediate context) ๋ฐ”๊นฅ์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ‘œ์ค€ ๊ทœ์ •์— ๋”ฐ๋ผ ์ด๋Š”ย SFINAEย ์˜ ์ ์šฉ ๋ฒ”์œ„๋ฅผ ๋„˜์–ด์„ญ๋‹ˆ๋‹ค. -๋ชจ๋‘์˜ ์ฝ”๋“œ
๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๊ฐ€ ์“ธ๋ฐ ์—†๋Š” ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋ฅผ ๋ฑ‰์ง€ ์•Š๊ฒŒ ํ•˜๋ ค๋ฉด, ํ•จ์ˆ˜ ๋‚ด๋ถ€๊ฐ€ ์•„๋‹Œ ํ•จ์ˆ˜์˜ ์„ ์–ธ๋ถ€์— ํƒ€์ž…์„ ๋„ฃ์–ด์•ผ โ€˜์น˜ํ™˜์‹คํŒจ๋กœ ์ธํ•œ ์ปดํŒŒ์ผ ํ›„๋ณด ์ œ์™ธ' ๋งŒ ์ผ์–ด๋‚˜๊ณ  โ€˜์ปดํŒŒ์ผ ์˜ค๋ฅ˜' ๋Š” ์ผ์–ด๋‚˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค. ์ด๋Ÿฐ SFINAE๋ฅผ ์ž˜ ์‚ฌ์šฉํ•˜๋Š” ํˆด ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฐ”๋กœ enable_if ์ด๋‹ค.
template <bool, typename T = void> struct enable_if {}; template <typename T> struct enable_if<true, T> { typedef T type; };
C++
๋ณต์‚ฌ
enable_if ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ๋ถ€ํ„ฐ ๋˜ ํ—ท๊ฐˆ๋ฆฐ๋‹ค.
์šฐ์„ , C++์—์„œ struct์™€ class ๋Š” ๊ฐ™๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ struct๋ฅผ ํด๋ž˜์Šค๋ผ๊ณ  ์นญํ•˜๋Š” ๋ธ”๋กœ๊ทธ๋‚˜ ๋ ˆํผ๋Ÿฐ์Šค๋„ ์žˆ์Œ!
template <bool, typename T = void> struct enable_if {};
์—์„œ typename T = void ๋Š” ์ž๋ฃŒํ˜•์ด ์•ˆ๋“ค์–ด์˜ค๋ฉด void๋ผ๊ณ  ํ•œ๋‹ค๋Š” ๋œป!
enable_if ์— ์ž๋ฃŒํ˜•์œผ๋กœ true, T ๊ฐ€ ๋“ค์–ด์˜ค๋ฉด T ํ˜•์‹์˜ type์ด ์ƒ๊ธด๋‹ค. ๋”ฐ๋ผ์„œ,
template <class T> typename std::enable_if<std::is_integral<T>::value, bool>::type is_odd (T i) {return bool(i%2);}
C++
๋ณต์‚ฌ
is_integral<T>::value ๊ฐ€ true ์ด๋ฉด enable_if์— type์ด๋ผ๋Š” bool์ž๋ฃŒํ˜•์˜ ํƒ€์ž…์ด ์ƒ๊ธฐ๊ธฐ ๋•Œ๋ฌธ์— ์œ„์˜ ์ฝ”๋“œ๊ฐ€ ์ปดํŒŒ์ผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ํ•˜์ง€๋งŒ ๋งŒ์•ฝ is_integral ์— ๋“ค์–ด๊ฐ„ ์ž๋ฃŒํ˜• T๊ฐ€ false, ์ฆ‰ ์ •์ˆ˜ํ˜•์ด ์•„๋‹Œ ์ž๋ฃŒํ˜•์ด๋ผ๋ฉด enable_if์—์„œ type์ด๋ผ๋Š” ๋ฉค๋ฒ„ํƒ€์ž…์ด ์ƒ๊ธฐ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋œฌ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๋Š” is_integral ์—ญ์‹œ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.
template <class T> struct is_integral;
C++
๋ณต์‚ฌ
is_integral์€ ์ž๋ฃŒํ˜• T๊ฐ€ ์ •์ˆ˜ ์œ ํ˜•์ธ์ง€ ์‹๋ณ„ํ•˜๋Š” ํด๋ž˜์Šค์ด๋‹ค.
T ๊ฐ€ ์ •์ˆ˜ ์œ ํ˜•์ธ์ง€์— ๋”ฐ๋ผ integral_constant ๋ฅผ true_type ํ˜น์€ false_type์œผ๋กœ ์ƒ์†๋ฐ›๋Š”๋‹ค.
integral_constant ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•์‹์ด๋‹ค. (๋งํฌ์ฐธ์กฐ)
template <class T, T v> struct integral_constant { static constexpr T value = v; typedef T value_type; typedef integral_constant<T,v> type; constexpr operator T() { return v; } };
C++
๋ณต์‚ฌ
์šฐ์„ , ์ฒ˜์Œ๋ณด๋Š” ์ € constexpr ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.
11๋ฒ„์ „๋ถ€ํ„ฐ ์“ฐ๋Š” ํ‘œํ˜„์ธ๊ฐ€๋ณด๋‹ค.
๊ทผ๋ฐ ์–ด์ฐจํ”ผ ์šฐ๋ฆฌ๊ฐ€ ์“ฐ๋ ค๋Š” ๊ธฐ๋Šฅ ๋‚ด์—์„œ๋Š” ์ € constexpr ์ด ๋ถ™์€ ๋ฉค๋ฒ„๋ฅผ ๋‹ค ๋นผ๋„ ํฐ ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๊ณ  ํ•œ๋‹คโ€ฆ (jseo๋‹˜์€ constexpr์„ const ๋กœ ํ–ˆ๋‹ค๊ณ  ํ•œ๋‹ค.)
๊ทผ๋ฐ ๋‹ค์‹œ ๋ณด๋‹ˆ ์œ„์˜ enable_if ์˜ˆ์‹œ์—์„œ template <class T> typename std::enable_if<std::is_integral<T>::value, bool>::type is_odd (T i) {return bool(i%2);} ์œผ๋กœ is_integral์˜ type์„ ์‚ฌ์šฉํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ฉค๋ฒ„ํƒ€์ž… value ๋Š” static const ๋กœ ๋„ฃ์–ด์•ผ ํ•  ๊ฒƒ ๊ฐ™๋‹ค.
๊ทธ๋Ÿผ ์ด์ œ integral_constant ๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•์‹์ด ๋œ๋‹ค.
template <class T, T v> struct integral_constant { static const T value = v; typedef T value_type; typedef integral_constant<T,v> type; };
C++
๋ณต์‚ฌ
v ๋กœ ์ดˆ๊ธฐํ™”๋œ static const T ํ˜•์‹์˜ value, T ํ˜•์‹์˜ value_type๊ณผ integral_constant ํ˜•์‹์˜ type์„ ๊ฐ€์ง„๋‹ค.
typedef integral_constant<bool, true> true_type; typedef integral_constant<bool, false> false_type;
C++
๋ณต์‚ฌ
integral_constant ์— bool, true ๊ฐ€ ๋“ค์–ด๊ฐ„ ํด๋ž˜์Šค๋ฅผ true_type์œผ๋กœ, false๊ฐ€ ๋“ค์–ด๊ฐ„ ํด๋ž˜์Šค๋ฅผ false_type ์œผ๋กœ typedef ์‹œ์ผœ๋‘”๋‹ค.
์ดํ›„ is_integral ์— ๋“ค์–ด์˜จ ์ž๋ฃŒํ˜•์ด ์ •์ˆ˜ํ˜•์ด๋ฉด true_type์„ ์ƒ์†๋ฐ›๊ณ , ์•„๋‹ˆ๋ฉด false_type์„ ์ƒ์†๋ฐ›๋Š”๋‹ค.
๊ทธ๋ ‡๊ฒŒ ์•„๋ž˜์ฒ˜๋Ÿผ ์จ๋ดค๋Š”๋ฐ
template <> struct is_integral<bool> : public true_type{}; template <> struct is_integral<char> : public true_type {}; template <> struct is_integral<unsigned char> : public true_type {}; . . .
C++
๋ณต์‚ฌ
๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ์„œ is_integral ์˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ฝ์–ด๋ณด๋‹ค๊ฐ€, ์ด๋Ÿฐ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋Š” ๊ฑธ ๋ฐœ๊ฒฌํ–ˆ๋‹ค.
All fundamental integral types, along with all their aliases (like those inย cstdint), are considered integral types by this class, including theirย const ย andย volatile qualified variants.
const ์™€ volatile ์—ญ์‹œ ํฌํ•จํ•œ๋‹ค๊ณ  ์จ์žˆ๋‹ค! volatile ์ด ๋ญ”์ง€๋Š” ์ž˜ ๋ชจ๋ฅด์ง€๋งŒ, ์ผ๋‹จ const๋งŒ ํ•˜๋”๋ผ๋„ ๋ชจ๋“  ์ž๋ฃŒํ˜•์— const๋ฅผ ๋ถ™์ธ ํ•จ์ˆ˜๋ฅผ ๋˜ ์จ์•ผ ํ•œ๋‹คโ€ฆ ์‹ฌ์ง€์–ด const volatile ๋„ ์žˆ๋‹ค๊ณ  ํ•˜๋‹ˆ, int ํ•˜๋‚˜์˜ ์ž๋ฃŒํ˜•์— int, const int, volatile int, const volatile int ์ด ๋„ค ๊ฐœ์˜ ํ…œํ”Œ๋ฆฟ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
์ด๋ฅผ ํ•ด๊ฒฐํ•ด์ฃผ๊ธฐ ์œ„ํ•ด, ์ฆ‰ ์ž๋ฃŒํ˜• ์•ž์— const์™€ volatile์„ ์—†์• ์ฃผ๊ธฐ ์œ„ํ•ด <type_traits> ํ—ค๋”์—๋Š” remove_cv ๋ผ๋Š” ํด๋ž˜์Šค ํ…œํ”Œ๋ฆฟ์ด ์กด์žฌํ•œ๋‹ค. (๋งํฌ)
template <class T> struct remove_cv { typedef T type; }; template <class T> struct remove_cv<const T> { typedef T type; }; template <class T> struct remove_cv<volatile T> { typedef T type; }; template <class T> struct remove_cv<const volatile T> { typedef T type; };
C++
๋ณต์‚ฌ
์ด๋ ‡๊ฒŒ ๋งŒ๋“  ํ›„ remove_cv::type ์„ ํ˜ธ์ถœํ•˜๋ฉด const ์™€ volatile์ด ๋ชจ๋‘ ์‚ญ์ œ๋œ type ๋งŒ ํ˜ธ์ถœ๋˜๊ฒŒ ๋œ๋‹ค.
๋‹ค์‹œ ์œ„์˜ enable_if ์ฝ”๋“œ๋ฅผ ๋ณด๊ณ  ์ •๋ฆฌํ•ด๋ณด๋ฉด
template <class T> typename std::enable_if<std::is_integral<T>::value, bool>::type is_odd (T i) {return bool(i%2);}
C++
๋ณต์‚ฌ
is_integral ์— ๋“ค์–ด์˜จ ์ž๋ฃŒํ˜• T ๊ฐ€ ์ •์ˆ˜๋ผ๋ฉด, SFINAE๊ฐ€ ์ ์šฉ๋œ enable_if์˜ type ์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜ค๋ฅ˜๊ฐ€ ๋‚˜์ง€ ์•Š๋Š”๋‹ค. T๊ฐ€ ์ •์ˆ˜ํ˜•์ด ์•„๋‹ˆ๋ผ๋ฉด, is_integral<T>::value ๊ฐ€ false๊ฐ€ ๋˜๊ณ , enable_if์˜ ์ฒซ๋ฒˆ์งธ ํƒ€์ž…์ด false ์ด๋ฉด ๋ฉค๋ฒ„ํƒ€์ž…์ด ์—†๋Š” enable_if ๊ฐ€ ์ƒ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋‚˜๊ฒŒ ๋œ๋‹ค!
(์“ฐ๋ฉด์„œ๋„ ์—„์ฒญ ํ—ท๊ฐˆ๋ฆฐ๋‹ค.)
์—ฌ๊ธฐ๊นŒ์ง€ ์ž˜ ์ดํ•ดํ•ด์„œ ์ •๋ฆฌํ•˜๋ฉด enable_if ์™€ is_integral ๋“ฑ <type_traits> ํ—ค๋”๋Š” ๊ตฌํ˜„๋!
๋‹ค์Œ์€ iterator ์ด๋‹ค.
allocator
<memory> ํ—ค๋”์— ์žˆ๋Š” ํด๋ž˜์Šค์ด๋‹ค.
์„œ๋ธŒ์ ํŠธ์— ๋ณด๋ฉด std::allocator ๋ฅผ ๋ฐ˜๋“œ์‹œ ์‚ฌ์šฉํ•˜๋ผ๋Š” ๋ฌธ๊ตฌ๊ฐ€ ์žˆ๋‹ค. ์ด allocator๊ฐ€ ๋ญ”์ง€ ์•Œ์•„๋ณด์ž.
vector์—๋Š” ๊ณต๊ฐ„์„ ํ• ๋‹นํ•ด์ฃผ๋Š” ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋“ค์ด ์žˆ๋‹ค. resize ๋“ฑ!
c++์—์„œ๋Š” ๊ณต๊ฐ„ ํ• ๋‹น์„ ํ• ๋•Œ new ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, new ์—ฐ์‚ฐ์ž๋Š”
1.
๊ธฐ๋ณธ ์ƒ์„ฑ์ž ํ•„์š”
2.
๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น
3.
์š”์†Œ ์ดˆ๊ธฐํ™”
3๊ฐ€์ง€ ์กฐ๊ฑด์ด ํ•„์š”ํ•˜๋‹ค.
ํ•˜์ง€๋งŒ ์ด ์„ธ๊ฐ€์ง€ ์กฐ๊ฑด์ด ์„ธํŠธ๋กœ ๋”ฐ๋ผ๋‹ค๋‹ˆ๊ฒŒ ๋˜์–ด์„œ ์ปดํ“จํ„ฐ ์ž์›์˜ ์‚ฌ์šฉ๋Ÿ‰์ด ์ƒ๋‹นํžˆ ์ฆ๊ฐ€ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ allocator๋ฅผ ์ด์šฉํ•˜์—ฌ ์œ„ ๋‹จ๊ณ„๋“ค์„ ๊ฐ๊ฐ ์›ํ• ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.
ํŠน์ • ์ปจํ…Œ์ด๋„ˆ์— ์ตœ์ ํ™”๋œ ์œ ์—ฐํ•œ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๊ณผ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ๋Œ€๋ถ€๋ถ„์˜ ์ปจํ…Œ์ด๋„ˆ๋“ค์€ allocator๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
๊ทธ๋Ÿฌ๋‹ˆ๊นŒ, new๋ฅผ ์“ฐ๋ฉด ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉฐ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•ด์ฃผ๊ณ , ํ•ด๋‹น ์ž๋ฃŒํ˜•์— ๋งž๊ฒŒ ์ดˆ๊ธฐํ™”๊นŒ์ง€ ํ•ด์ค€๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด vector<int>๋ฅผ new๋กœ ํ• ๋‹นํ•˜๋ฉด ๊ณต๊ฐ„ ํ• ๋‹น์„ ํ•œ ํ›„ ์ดˆ๊ธฐํ™”๊ฐ€ ๋˜๊ณ , ์ดํ›„ ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉํ•  ๋•Œ ํ•œ๋ฒˆ ๋” ์ดˆ๊ธฐํ™” ๋œ๋‹ค. ์ดˆ๊ธฐํ™”๊ฐ€ ํ•˜๋‚˜์˜ ์š”์†Œ๋งˆ๋‹ค ๋‘๋ฒˆ์”ฉ ์ง„ํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ž์› ๋‚ญ๋น„๊ฐ€ ์‹ฌํ•˜๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
ํ•˜์ง€๋งŒ allocator ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น๋งŒ ํ•˜๊ณ  ์ดˆ๊ธฐํ™”๋ฅผ ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ ๊ฐ์ฒด๊ฐ€ ๋“ค์–ด์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ํ•ด์ œ(deallocate) ํ•˜์ง€ ์•Š๊ณ  (์žฌํ• ๋‹น ํ•˜์ง€ ์•Š๊ณ ) ์ดˆ๊ธฐ ์ƒํƒœ๋กœ ๋Œ๋ฆด ์ˆ˜ ์žˆ๋‹ค. (๊ฐ์ฒด๋งŒ ์†Œ๋ฉธ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.destroy)
์–˜๋„ค๋Š” ๊ตฌํ˜„๋œ std ์“ฐ๋Š”๊ฑฐ๋ผ ๊ตฌํ˜„๊นŒ์ง€๋Š” ์•ˆํ•ด๋„ ๋œ๋‹ค! ๊ทผ๋ฐ ์ดํ•ด๋Š” ํ™•์‹คํžˆ ํ•ด์•ผํ•œ๋‹ค. ๋ฌด์Šจ ํ•จ์ˆ˜๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์•Œ์•„์•ผ ๋‚˜์ค‘์— ๋ฒกํ„ฐ์˜ capacity, resize, size ๋“ฑ์„ ๊ตฌํ˜„ํ•  ๋•Œ ์ž˜ ์“ธ ์ˆ˜ ์žˆ๋‹ค.
capacity โ‡’ allocate
size โ‡’ allocate + ์ดˆ๊ธฐํ™”
(๋งž๋‚˜?)
pair
std::pair ๊ณผ std::make_pair ๋ฅผ ๊ตฌํ˜„ํ•˜๋ผ๊ณ  ๋˜์–ด์žˆ๋‹ค.
๋‹ค๋ฅธ์• ๋“ค์€ ์„œ๋ธŒ์ ํŠธ์— std:: ๊ฐ€ ์•ˆ๋ถ™์–ด์žˆ๋Š”๋ฐ ์–˜๋Š” ์™œ ๋ถ™์–ด์žˆ์„๊นŒ?
std::pair::pair ์ด ์žˆ๋˜๋ฐ ์–˜๋•Œ๋ฌธ์ธ๊ฐ€
equal
template <class InputIterator1, class InputIterator2> bool equal (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);
C++
๋ณต์‚ฌ
first1~last1 ๋ฒ”์œ„์™€ first2~ ์•ž ๋ฒ”์œ„์˜ ๊ฐœ์ˆ˜๋งŒํผ์˜ ๋ฒ”์œ„ ์š”์†Œ๊ฐ€ ๋ชจ๋‘ ๊ฐ™์œผ๋ฉด true ๋ฆฌํ„ด!
lexicographical_compare
template <class InputIterator1, class InputIterator2> bool lexicographical_compare (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2);
C++
๋ณต์‚ฌ
first1~last1 ๋ฒ”์œ„์˜ ์š”์†Œ๊ฐ€ first2~last2 ๋ฒ”์œ„์˜ ์š”์†Œ๋ณด๋‹ค ์ž‘์œผ๋ฉด true!
// lexicographical_compare example#include <iostream>// std::cout, std::boolalpha#include <algorithm>// std::lexicographical_compare#include <cctype>// std::tolower// a case-insensitive comparison function: bool mycomp (char c1,char c2) {return std::tolower(c1)<std::tolower(c2); } int main () { char foo[]="Apple"; char bar[]="apartment"; std::cout << std::boolalpha; std::cout <<"Comparing foo and bar lexicographically (foo<bar):\n"; std::cout <<"Using default comparison (operator<): "; std::cout << std::lexicographical_compare(foo,foo+5,bar,bar+9); std::cout <<'\n'; std::cout <<"Using mycomp as comparison object: "; std::cout << std::lexicographical_compare(foo,foo+5,bar,bar+9,mycomp); std::cout <<'\n'; return 0; }
C++
๋ณต์‚ฌ

vector ๊ตฌํ˜„

๋ ˆํผ๋Ÿฐ์Šค์— ๋‚˜์™€์žˆ๋Š” ๊ฒƒ์„ ํ† ๋Œ€๋กœ C++11 ๋ฒ„์ „ ์ด์ „์˜ (98๋ฒ„์ „์˜) ๋ฉค๋ฒ„๋“ค๊ณผ ํ•จ์ˆ˜๋“ค์„ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.
๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋กœ๋Š”
pointer _begin; pointer _end; pointer _end_cap; allocator_type _alloc;
C++
๋ณต์‚ฌ
_end๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ์˜ end๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ
_end_cap ์€ capacity์˜ end๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค. ์ฆ‰, capacity ์šฉ๋Ÿ‰์˜ end ํฌ์ธํ„ฐ ์ธ๋“ฏ!

Reference

GitHub - yongjulejule/ft_containers at fa4e0535dcdd04d911ac8c2ae5bf5c8e0cdd73d7
My c++ STL containers (c++98) STL์˜ ๋ฉ”์†Œ๋“œ๋“ค์— ๋งž๊ฒŒ, snake_case ์‚ฌ์šฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”์†Œ๋“œ, ํด๋ž˜์Šค๋Š” __class_name ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ์ž‘์„ฑ ์™ธ๋ถ€๋กœ ๊ณต๊ฐœ๋˜์ง€ ์•Š๋Š” ๋ณ€์ˆ˜๋Š” _variable_name ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ์ž‘์„ฑ format๋Š” google style guide์— ๋”ฐ๋ฆ„ privateํ•œ ํด๋ž˜์Šค __class_name privateํ•œ type์€ _Type_Name private ๋ฉค๋ฒ„ ๋ณ€์ˆ˜ _variable_name privateํ•œ ํ•จ์ˆ˜์˜ ์ง€์—ญ๋ณ€์ˆ˜ __variable_name c++98 ๊ธฐ์ค€ ๋ชจ๋“  ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๊ฐ™์€ exception-safety๋ฅผ ๋ณด์žฅ c++98๋กœ ๊ฐ€๋Šฅํ•œ Template Meta Programming ์ตœ๋Œ€ํ•œ ํ™œ์šฉ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์žˆ์–ด ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ๋“ค์„ class template๋กœ ๋งŒ๋“ค์–ด ๋‘ฌ์„œ ๋‹ค๋ฅธ object๋“ค์„ element๋กœ ์ž๋ฃŒ๊ตฌ์กฐ์— ๋งž๊ฒŒ ์ €์žฅํ•ด์คŒ.