๐Ÿš€ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„: C++๋กœ ๋– ๋‚˜๋Š” ์ฝ”๋”ฉ ์—ฌํ–‰! ๐ŸŒŸ

์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿš€ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„: C++๋กœ ๋– ๋‚˜๋Š” ์ฝ”๋”ฉ ์—ฌํ–‰! ๐ŸŒŸ

 

 

์•ˆ๋…•ํ•˜์„ธ์š”, ์ฝ”๋”ฉ ๊ฟˆ๋‚˜๋ฌด๋“ค! ์˜ค๋Š˜์€ C++์˜ ์„ธ๊ณ„๋กœ ์—ฌ๋Ÿฌ๋ถ„์„ ์ดˆ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ํƒ€์ž… ๋ฆฌ์ŠคํŠธ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„์ด๋ผ๋Š” ์ฃผ์ œ๋กœ ์žฌ๋ฏธ์žˆ๊ณ  ์œ ์ตํ•œ ์‹œ๊ฐ„์„ ๋ณด๋‚ด๋ณผ ๊ฑฐ์˜ˆ์š”. ์ด ์—ฌํ–‰์ด ๋๋‚  ๋•Œ์ฏค์ด๋ฉด ์—ฌ๋Ÿฌ๋ถ„๋„ C++ ๋งˆ์Šคํ„ฐ๊ฐ€ ๋  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”! (๋ฌผ๋ก  ๋†๋‹ด์ด๊ณ ์š”, ใ…‹ใ…‹ใ…‹ ํ•˜์ง€๋งŒ ๋งŽ์ด ๋ฐฐ์šฐ์‹ค ๊ฑฐ์˜ˆ์š”!)

์šฐ๋ฆฌ์˜ ์—ฌ์ •์„ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์—, ์ž ๊น! ์—ฌ๋Ÿฌ๋ถ„, ํ˜น์‹œ '์žฌ๋Šฅ๋„ท'์ด๋ผ๋Š” ์‚ฌ์ดํŠธ ๋“ค์–ด๋ณด์…จ๋‚˜์š”? ์ฝ”๋”ฉ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค์–‘ํ•œ ์žฌ๋Šฅ์„ ๊ฑฐ๋ž˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ณณ์ด๋ผ๊ณ  ํ•˜๋”๋ผ๊ณ ์š”. ๋‚˜์ค‘์— ์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์šด C++ ์‹ค๋ ฅ์„ ๋ฝ๋‚ด๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ณณ์ด ๋  ์ˆ˜๋„ ์žˆ๊ฒ ์–ด์š”. ์–ด์ฉŒ๋ฉด ์—ฌ๋Ÿฌ๋ถ„์˜ ์ฝ”๋”ฉ ์‹ค๋ ฅ์œผ๋กœ ๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ์„์ง€๋„ ๋ชจ๋ฅด์ฃ ! ๐Ÿ˜‰

์ž, ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์‹œ์ž‘ํ•ด๋ณผ๊นŒ์š”? ์•ˆ์ „๋ฒจํŠธ ๋งค์„ธ์š”! ์šฐ๋ฆฌ์˜ C++ ์šฐ์ฃผ์„ ์ด ๊ณง ์ด๋ฅ™ํ•ฉ๋‹ˆ๋‹ค! ๐Ÿš€

๐Ÿ“š ํƒ€์ž… ๋ฆฌ์ŠคํŠธ: C++์˜ ๋งˆ๋ฒ• ์ƒ์ž

์—ฌ๋Ÿฌ๋ถ„, ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ผ๊ณ  ๋“ค์–ด๋ณด์…จ๋‚˜์š”? ์•„๋‹ˆ๋ฉด ์ฒ˜์Œ ๋“ฃ๋Š” ๋ง์ด๋ผ "๋ญ์•ผ, ์ด๊ฒŒ?" ํ•˜๊ณ  ๊ณ„์‹ ๊ฐ€์š”? ๊ฑฑ์ • ๋งˆ์„ธ์š”! ์ง€๊ธˆ๋ถ€ํ„ฐ ์ฐจ๊ทผ์ฐจ๊ทผ ์„ค๋ช…ํ•ด๋“œ๋ฆด๊ฒŒ์š”. ๐Ÿค“

ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋Š” C++์˜ ํ…œํ”Œ๋ฆฟ ๋ฉ”ํƒ€ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์•„์ฃผ ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์˜ˆ์š”. ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด, ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ํƒ€์ž…์„ ํ•˜๋‚˜์˜ ๋ฆฌ์ŠคํŠธ๋กœ ๋ฌถ์–ด๋†“์€ ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋ผ์š”. ๋งˆ์น˜ ์šฐ๋ฆฌ๊ฐ€ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฌผ๊ฑด์„ ๋‹ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”!

๐Ÿ›’ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ = C++์˜ ์žฅ๋ฐ”๊ตฌ๋‹ˆ

int, float, double, char ๋“ฑ ์—ฌ๋Ÿฌ ํƒ€์ž…์„ ํ•œ ๋ฒˆ์— ๋‹ด์•„์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”!

๊ทผ๋ฐ ์™œ ์ด๋Ÿฐ ๊ฒŒ ํ•„์š”ํ• ๊นŒ์š”? ๐Ÿค” ์ž, ์ƒ์ƒํ•ด๋ณด์„ธ์š”. ์—ฌ๋Ÿฌ๋ถ„์ด ์Šˆํผ์— ์žฅ์„ ๋ณด๋Ÿฌ ๊ฐ”๋Š”๋ฐ, ๋ฌผ๊ฑด๋งˆ๋‹ค ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ์žฅ๋ฐ”๊ตฌ๋‹ˆ๋ฅผ ๋“ค๊ณ  ๋‹ค๋…€์•ผ ํ•œ๋‹ค๋ฉด ์–ด๋–จ๊นŒ์š”? ๊ณผ์ผ์šฉ, ์ฑ„์†Œ์šฉ, ๊ณผ์ž์šฉ... ์—„์ฒญ ๋ถˆํŽธํ•˜๊ฒ ์ฃ ? ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์˜ˆ์š”. ์—ฌ๋Ÿฌ ํƒ€์ž…์„ ํ•œ ๋ฒˆ์— ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ๊นŒ ์ฝ”๋“œ๊ฐ€ ํ›จ์”ฌ ๊น”๋”ํ•ด์ง€๊ณ  ํšจ์œจ์ ์ด ๋˜๋Š” ๊ฑฐ์˜ˆ์š”!

์ž, ์ด์ œ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ๋งŒ๋“œ๋Š”์ง€ ํ•œ๋ฒˆ ๋ณผ๊นŒ์š”? C++์—์„œ๋Š” ๋ณดํ†ต ์ด๋ ‡๊ฒŒ ์ƒ๊ฒผ์–ด์š”:


template <typename... Types>
struct TypeList {};

์–ด๋•Œ์š”? ์ƒ๊ฐ๋ณด๋‹ค ๊ฐ„๋‹จํ•˜์ฃ ? ใ…‹ใ…‹ใ…‹ ์ด๊ฒŒ ๋ฐ”๋กœ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ์˜ ๊ธฐ๋ณธ ํ˜•ํƒœ์˜ˆ์š”. 'typename...'์€ ๊ฐ€๋ณ€ ํ…œํ”Œ๋ฆฟ ๋งค๊ฐœ๋ณ€์ˆ˜๋ผ๊ณ  ํ•˜๋Š”๋ฐ, ์‰ฝ๊ฒŒ ๋งํ•ด "์•ผ, ๋„ˆ๋„ค ๋ช‡ ๊ฐœ๋“  ๋‹ค ๋“ค์–ด์™€!"๋ผ๊ณ  ์™ธ์น˜๋Š” ๊ฑฐ์˜ˆ์š”. ๐Ÿ˜†

์ด์ œ ์ด ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•ด๋ณผ๊นŒ์š”?


using MyList = TypeList<int, float, double, char>;

์งœ์ž”! ๐ŸŽ‰ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด int, float, double, char ํƒ€์ž…์„ ๋ชจ๋‘ ํฌํ•จํ•˜๋Š” MyList๋ผ๋Š” ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋งŒ๋“ค์–ด์ ธ์š”. ๊ทผ๋ฐ ์ด๋ ‡๊ฒŒ๋งŒ ํ•˜๋ฉด ์žฌ๋ฏธ์—†๊ฒ ์ฃ ? ์ด ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋กœ ๋ญ˜ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณผ๊ฒŒ์š”!

๐Ÿ•ต๏ธโ€โ™€๏ธ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ ํƒํ—˜ํ•˜๊ธฐ

ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค์—ˆ์œผ๋‹ˆ, ์ด์ œ ์ด๊ฑธ ๊ฐ€์ง€๊ณ  ๋†€์•„๋ณผ ์ฐจ๋ก€์˜ˆ์š”! ์šฐ๋ฆฌ๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ์žฌ๋ฏธ์žˆ๋Š” ์ž‘์—…๋“ค์„ ์†Œ๊ฐœํ•ด๋“œ๋ฆด๊ฒŒ์š”.

  1. ํƒ€์ž… ๊ฐœ์ˆ˜ ์„ธ๊ธฐ
  2. ํŠน์ • ํƒ€์ž… ์ฐพ๊ธฐ
  3. ํƒ€์ž… ์ถ”๊ฐ€ํ•˜๊ธฐ
  4. ํƒ€์ž… ์ œ๊ฑฐํ•˜๊ธฐ
  5. ํƒ€์ž… ๋ณ€ํ™˜ํ•˜๊ธฐ

ํ•˜๋‚˜์”ฉ ์‚ดํŽด๋ณผ๊นŒ์š”? ๐Ÿ˜Ž

1. ํƒ€์ž… ๊ฐœ์ˆ˜ ์„ธ๊ธฐ

์šฐ๋ฆฌ์˜ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ์— ๋ช‡ ๊ฐœ์˜ ํƒ€์ž…์ด ๋“ค์–ด์žˆ๋Š”์ง€ ์„ธ์–ด๋ณผ๊นŒ์š”? ์ด๋Ÿฐ ์‹์œผ๋กœ ํ•  ์ˆ˜ ์žˆ์–ด์š”:


template <typename... Types>
struct CountTypes;

template <>
struct CountTypes<> {
    static constexpr size_t value = 0;
};

template <typename T, typename... Rest>
struct CountTypes<T, Rest...> {
    static constexpr size_t value = 1 + CountTypes<Rest...>::value;
};

// ์‚ฌ์šฉ ์˜ˆ
using MyList = TypeList<int, float, double, char>;
constexpr size_t count = CountTypes<MyList>::value;
// count๋Š” 4๊ฐ€ ๋ฉ๋‹ˆ๋‹ค!

์šฐ์™€! ๐Ÿ˜ฎ ์ด๊ฒŒ ๋ญ”๊ฐ€ ์‹ถ์ฃ ? ๊ฑฑ์ • ๋งˆ์„ธ์š”, ์ฒœ์ฒœํžˆ ์„ค๋ช…ํ•ด๋“œ๋ฆด๊ฒŒ์š”.

์ด ์ฝ”๋“œ๋Š” ์žฌ๊ท€์ ์œผ๋กœ ๋™์ž‘ํ•ด์š”. ๋งˆ์น˜ ๋Ÿฌ์‹œ์•„ ์ธํ˜•์ฒ˜๋Ÿผ ํ•˜๋‚˜์”ฉ ์—ด์–ด๋ณด๋ฉด์„œ ์•ˆ์— ๋ญ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฑฐ์ฃ . ์ฒ˜์Œ์—๋Š” ์ „์ฒด ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ณด๊ณ , ๊ทธ ๋‹ค์Œ์—๋Š” ์ฒซ ๋ฒˆ์งธ ํƒ€์ž…์„ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€๋ฅผ ๋ณด๊ณ , ๋˜ ๊ทธ ๋‹ค์Œ์—๋Š”... ์ด๋Ÿฐ ์‹์œผ๋กœ ๊ณ„์† ๊ฐ€๋‹ค ๋ณด๋ฉด ๊ฒฐ๊ตญ ๋นˆ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋˜๊ฒ ์ฃ ? ๊ทธ๋•Œ 0์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๋๋‚˜๋Š” ๊ฑฐ์˜ˆ์š”.

๊ฐ ๋‹จ๊ณ„๋งˆ๋‹ค 1์”ฉ ๋”ํ•ด์ฃผ๋‹ˆ๊นŒ, ๊ฒฐ๊ตญ ์ „์ฒด ํƒ€์ž…์˜ ๊ฐœ์ˆ˜๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๊ฑฐ์˜ˆ์š”! ์‹ ๊ธฐํ•˜์ฃ ? ใ…‹ใ…‹ใ…‹

2. ํŠน์ • ํƒ€์ž… ์ฐพ๊ธฐ

์ด๋ฒˆ์—” ์šฐ๋ฆฌ์˜ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ์— ํŠน์ • ํƒ€์ž…์ด ์žˆ๋Š”์ง€ ์ฐพ์•„๋ณผ๊นŒ์š”? ๋งˆ์น˜ "์›”๋ฆฌ๋ฅผ ์ฐพ์•„๋ผ" ๊ฒŒ์ž„์ฒ˜๋Ÿผ์š”! ๐Ÿ•ต๏ธโ€โ™‚๏ธ


template <typename T, typename List>
struct Contains;

template <typename T>
struct Contains<T, TypeList<>> {
    static constexpr bool value = false;
};

template <typename T, typename First, typename... Rest>
struct Contains<T, TypeList<First, Rest...>> {
    static constexpr bool value = 
        std::is_same_v<T, First> || Contains<T, TypeList<Rest...>>::value;
};

// ์‚ฌ์šฉ ์˜ˆ
using MyList = TypeList<int, float, double, char>;
constexpr bool hasInt = Contains<int, MyList>::value;  // true
constexpr bool hasString = Contains<std::string, MyList>::value;  // false

์ด ์ฝ”๋“œ๋„ ์žฌ๊ท€์ ์œผ๋กœ ๋™์ž‘ํ•ด์š”. ํƒ€์ž… ๋ฆฌ์ŠคํŠธ์˜ ๊ฐ ํƒ€์ž…์„ ํ•˜๋‚˜์”ฉ ํ™•์ธํ•˜๋ฉด์„œ, ์šฐ๋ฆฌ๊ฐ€ ์ฐพ๋Š” ํƒ€์ž…๊ณผ ๊ฐ™์€์ง€ ๋น„๊ตํ•˜๋Š” ๊ฑฐ์ฃ . ๋งŒ์•ฝ ๊ฐ™์€ ํƒ€์ž…์„ ์ฐพ์œผ๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๋๊นŒ์ง€ ์ฐพ์ง€ ๋ชปํ•˜๋ฉด false๋ฅผ ๋ฐ˜ํ™˜ํ•ด์š”.

์ด๋Ÿฐ ์‹์œผ๋กœ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ "ํƒํ—˜"ํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ๋ณด๋ฌผ์ฐพ๊ธฐ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์žฌ๋ฏธ์žˆ์ง€ ์•Š๋‚˜์š”? ๐Ÿ˜„

3. ํƒ€์ž… ์ถ”๊ฐ€ํ•˜๊ธฐ

์ด๋ฒˆ์—๋Š” ์šฐ๋ฆฌ์˜ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ์— ์ƒˆ๋กœ์šด ํƒ€์ž…์„ ์ถ”๊ฐ€ํ•ด๋ณผ๊นŒ์š”? ๋งˆ์น˜ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์ƒˆ๋กœ์šด ๋ฌผ๊ฑด์„ ๋‹ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ๐Ÿ›๏ธ


template <typename T, typename List>
struct Prepend;

template <typename T, typename... Types>
struct Prepend<T, TypeList<Types...>> {
    using type = TypeList<T, Types...>;
};

// ์‚ฌ์šฉ ์˜ˆ
using MyList = TypeList<int, float, double>;
using NewList = Prepend<char, MyList>::type;  // TypeList<char, int, float, double>

์ด ์ฝ”๋“œ๋Š” ์ƒˆ๋กœ์šด ํƒ€์ž…์„ ๋ฆฌ์ŠคํŠธ์˜ ๋งจ ์•ž์— ์ถ”๊ฐ€ํ•ด์š”. ๋งˆ์น˜ ์ค„ ์„œ๊ธฐํ•  ๋•Œ ์ƒˆ๋กœ์šด ์นœ๊ตฌ๊ฐ€ ๋งจ ์•ž์— ๋ผ์–ด๋“œ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ใ…‹ใ…‹ใ…‹

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ธฐ์กด์˜ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋Š” ๊ทธ๋Œ€๋กœ ๋‘๊ณ , ์ƒˆ๋กœ์šด ํƒ€์ž…์ด ์ถ”๊ฐ€๋œ ์ƒˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ๊ผญ ํ•„์š”ํ•  ๋•Œ๋งŒ ์ƒˆ ์นœ๊ตฌ๋ฅผ ์ดˆ๋Œ€ํ•˜๋Š” ๊ฑฐ์ฃ ! ๐Ÿ˜‰

4. ํƒ€์ž… ์ œ๊ฑฐํ•˜๊ธฐ

๋•Œ๋กœ๋Š” ํƒ€์ž… ๋ฆฌ์ŠคํŠธ์—์„œ ํŠน์ • ํƒ€์ž…์„ ์ œ๊ฑฐํ•ด์•ผ ํ•  ๋•Œ๋„ ์žˆ์–ด์š”. ๋งˆ์น˜ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์—์„œ ํ•„์š” ์—†๋Š” ๋ฌผ๊ฑด์„ ๋นผ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ๐Ÿ—‘๏ธ


template <typename T, typename List>
struct Remove;

template <typename T>
struct Remove<T, TypeList<>> {
    using type = TypeList<>;
};

template <typename T, typename... Rest>
struct Remove<T, TypeList<T, Rest...>> {
    using type = typename Remove<T, TypeList<Rest...>>::type;
};

template <typename T, typename First, typename... Rest>
struct Remove<T, TypeList<First, Rest...>> {
    using type = typename Prepend<First, typename Remove<T, TypeList<Rest...>>::type>::type;
};

// ์‚ฌ์šฉ ์˜ˆ
using MyList = TypeList<int, float, int, double, int>;
using NoIntList = Remove<int, MyList>::type;  // TypeList<float, double>

์šฐ์™€, ์ด๊ฑด ์ข€ ๋ณต์žกํ•ด ๋ณด์ด์ฃ ? ๐Ÿ˜… ํ•˜์ง€๋งŒ ๊ฑฑ์ • ๋งˆ์„ธ์š”! ์ฒœ์ฒœํžˆ ์„ค๋ช…ํ•ด๋“œ๋ฆด๊ฒŒ์š”.

์ด ์ฝ”๋“œ๋Š” ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ ์ œ๊ฑฐํ•˜๊ณ  ์‹ถ์€ ํƒ€์ž…์„ ๋งŒ๋‚˜๋ฉด ๊ทธ๋ƒฅ ๊ฑด๋„ˆ๋›ฐ๊ณ , ๋‹ค๋ฅธ ํƒ€์ž…๋“ค์€ ์ƒˆ ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•ด์š”. ๋งˆ์น˜ ๋ถˆ๋Ÿ‰ํ’ˆ์„ ๊ณจ๋ผ๋‚ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ใ…‹ใ…‹ใ…‹

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์›ํ•˜๋Š” ํƒ€์ž…์„ ๋ชจ๋‘ ์ œ๊ฑฐํ•œ ์ƒˆ๋กœ์šด ๋ฆฌ์ŠคํŠธ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์–ด์š”. ๊น”๋”ํ•˜์ฃ ? ๐Ÿ˜Ž

5. ํƒ€์ž… ๋ณ€ํ™˜ํ•˜๊ธฐ

๋งˆ์ง€๋ง‰์œผ๋กœ, ํƒ€์ž… ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ํƒ€์ž…์„ ๋‹ค๋ฅธ ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•ด๋ณผ๊นŒ์š”? ๋งˆ์น˜ ๋งˆ๋ฒ•์‚ฌ๊ฐ€ ๋ฌผ๊ฑด๋“ค์„ ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ๋ณ€์‹ ์‹œํ‚ค๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ๐Ÿง™โ€โ™‚๏ธโœจ


template <template <typename> class F, typename List>
struct Transform;

template <template <typename> class F>
struct Transform<F, TypeList<>> {
    using type = TypeList<>;
};

template <template <typename> class F, typename First, typename... Rest>
struct Transform<F, TypeList<First, Rest...>> {
    using type = typename Prepend<typename F<First>::type, 
                                  typename Transform<F, TypeList<Rest...>>::type>::type;
};

// ์‚ฌ์šฉ ์˜ˆ
template <typename T>
struct MakePointer {
    using type = T*;
};

using MyList = TypeList<int, float, double>;
using PointerList = Transform<MakePointer, MyList>::type;  // TypeList<int*, float*, double*>

์ด ์ฝ”๋“œ๋Š” ํƒ€์ž… ๋ฆฌ์ŠคํŠธ์˜ ๊ฐ ํƒ€์ž…์— ์–ด๋–ค "๋ณ€ํ™˜ ๋งˆ๋ฒ•"์„ ์ ์šฉํ•ด์š”. ์—ฌ๊ธฐ์„œ๋Š” ๋ชจ๋“  ํƒ€์ž…์„ ํฌ์ธํ„ฐ ํƒ€์ž…์œผ๋กœ ๋ฐ”๊พธ๋Š” ๋งˆ๋ฒ•์„ ์ผ์–ด์š”! ใ…‹ใ…‹ใ…‹

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์›๋ž˜ ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ํƒ€์ž…์„ ํ•œ ๋ฒˆ์— ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ •๋ง ๊ฐ•๋ ฅํ•œ ๋งˆ๋ฒ•์ด์ฃ ? ๐ŸŽฉโœจ

์ž, ์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋กœ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋ณธ์ ์ธ ์ž‘์—…๋“ค์ด์—์š”. ์–ด๋•Œ์š”? ์ƒ๊ฐ๋ณด๋‹ค ์žฌ๋ฏธ์žˆ์ฃ ? ๐Ÿ˜„

์ด๋Ÿฐ ๊ธฐ์ˆ ๋“ค์„ ์ž˜ ํ™œ์šฉํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ C++ ์ฝ”๋“œ๋ฅผ ๋”์šฑ ์œ ์—ฐํ•˜๊ณ  ๊ฐ•๋ ฅํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ์žฌ๋Šฅ๋„ท์—์„œ ๋‹ค์–‘ํ•œ ์žฌ๋Šฅ์„ ์กฐํ•ฉํ•ด์„œ ์ƒˆ๋กœ์šด ๊ฐ€์น˜๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ๐ŸŒŸ

๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ์ด๋Ÿฐ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ•˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„์— ์–ด๋–ป๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณผ ๊ฑฐ์˜ˆ์š”. ๊ธฐ๋Œ€๋˜์ง€ ์•Š๋‚˜์š”? ๐Ÿ˜‰

๐Ÿง  ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„: C++๋กœ ๋ฌธ์ œ ํ•ด๊ฒฐํ•˜๊ธฐ

์ž, ์ด์ œ ์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์šด ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์‹ค์ œ๋กœ ๋ญ”๊ฐ€๋ฅผ ํ•ด๋ณผ ์ฐจ๋ก€์˜ˆ์š”! ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„์ด๋ผ๊ณ  ํ•˜๋ฉด ๋ญ”๊ฐ€ ์–ด๋ ค์šธ ๊ฒƒ ๊ฐ™์ฃ ? ํ•˜์ง€๋งŒ ๊ฑฑ์ • ๋งˆ์„ธ์š”. ์šฐ๋ฆฌ๊ฐ€ ํ•จ๊ป˜ ํ•˜๋‚˜์”ฉ ํ•ด๋ณผ ๊ฑฐ๋‹ˆ๊นŒ์š”! ๐Ÿ˜Š

์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ž€ ๋ญ˜๊นŒ์š”? ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด, ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋‹จ๊ณ„๋ณ„ ๋ฐฉ๋ฒ•์ด์—์š”. ๋งˆ์น˜ ์š”๋ฆฌ ๋ ˆ์‹œํ”ผ์ฒ˜๋Ÿผ์š”! ์žฌ๋ฃŒ(๋ฐ์ดํ„ฐ)๋ฅผ ๊ฐ€์ง€๊ณ  ์–ด๋–ค ์ˆœ์„œ๋กœ ๋ฌด์—‡์„ ํ•ด์•ผ ๋ง›์žˆ๋Š” ์š”๋ฆฌ(๊ฒฐ๊ณผ)๊ฐ€ ๋‚˜์˜ค๋Š”์ง€ ์ •ํ•ด๋†“์€ ๊ฑฐ์ฃ .

C++์—์„œ๋Š” ์ด๋Ÿฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ•  ๋•Œ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์ •๋ง ๋ฉ‹์ง„ ์ผ๋“ค์„ ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊นŒ์š”?

๐ŸŽญ ๋‹คํ˜•์„ฑ ํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ

์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์šด ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ์ด์šฉํ•ด์„œ ์—ฌ๋Ÿฌ ํƒ€์ž…์— ๋Œ€ํ•ด ๋™์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ณผ ๊ฑฐ์˜ˆ์š”. ์ด๊ฑธ "๋‹คํ˜•์„ฑ ํ•จ์ˆ˜"๋ผ๊ณ  ํ•ด์š”. ์–ด๋ ค์›Œ ๋ณด์ด์ง€๋งŒ, ์‹ค์ œ๋กœ ํ•ด๋ณด๋ฉด ์žฌ๋ฏธ์žˆ์„ ๊ฑฐ์˜ˆ์š”! ใ…‹ใ…‹ใ…‹


template <typename T>
void print(const T& value) {
    std::cout << value << std::endl;
}

template <typename... Types>
void printAll(const Types&... args) {
    (print(args), ...);
}

// ์‚ฌ์šฉ ์˜ˆ
printAll(1, 3.14, "Hello", 'A');

์ด ์ฝ”๋“œ๋Š” ๋ญ˜ ํ•˜๋Š” ๊ฑธ๊นŒ์š”? ๐Ÿ˜ฎ ๊ฐ„๋‹จํ•ด์š”! ์–ด๋–ค ํƒ€์ž…์˜ ๊ฐ’์ด๋“  ๋ฐ›์•„์„œ ์ถœ๋ ฅํ•ด์ฃผ๋Š” ๊ฑฐ์˜ˆ์š”. int๋“ , double์ด๋“ , string์ด๋“ , char๋“  ์ƒ๊ด€์—†์ด์š”!

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์šฐ๋ฆฌ๊ฐ€ ์–ด๋–ค ํƒ€์ž…์„ ๋„ฃ๋“  ์•Œ์•„์„œ ์ฒ˜๋ฆฌํ•ด์ค˜์š”. ๋งˆ์น˜ ๋งŒ๋Šฅ ์š”๋ฆฌ์‚ฌ์ฒ˜๋Ÿผ์š”! ๐Ÿ‘จโ€๐Ÿณ

์ด๋Ÿฐ ๊ธฐ๋Šฅ์€ ์‹ค์ œ๋กœ ๋งŽ์ด ์“ฐ์—ฌ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ๋Šฅ๋„ท๊ฐ™์€ ํ”Œ๋žซํผ์—์„œ ๋‹ค์–‘ํ•œ ์œ ํ˜•์˜ ์žฌ๋Šฅ์„ ํ•œ ๋ฒˆ์— ํ‘œ์‹œํ•ด์•ผ ํ•  ๋•Œ ์ด๋Ÿฐ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ ?

๐Ÿƒโ€โ™‚๏ธ ํƒ€์ž… ๊ธฐ๋ฐ˜ ๋ถ„๊ธฐ ์ฒ˜๋ฆฌ

์ด๋ฒˆ์—๋Š” ์กฐ๊ธˆ ๋” ๋ณต์žกํ•œ ๊ฑธ ํ•ด๋ณผ๊นŒ์š”? ํƒ€์ž…์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋™์ž‘์„ ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ณผ ๊ฑฐ์˜ˆ์š”. ๋งˆ์น˜ ๊ตํ†ต ์‹ ํ˜ธ๋“ฑ์ฒ˜๋Ÿผ, ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๋ฐ˜์‘ํ•˜๋Š” ๊ฑฐ์ฃ ! ๐Ÿšฆ


template <typename T>
struct TypeIdentity {
    using type = T;
};

template <typename T>
void process(T value, TypeIdentity<int>) {
    std::cout << "์ •์ˆ˜ ์ฒ˜๋ฆฌ: " << value * 2 << std::endl;
}

template <typename T>
void process(T value, TypeIdentity<double>) {
    std::cout << "์‹ค์ˆ˜ ์ฒ˜๋ฆฌ: " << value / 2.0 << std::endl;
}

template <typename T>
void process(T value, TypeIdentity<std::string>) {
    std::cout << "๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ: " << value + "!" << std::endl;
}

template <typename T>
void smartProcess(T value) {
    process(value, TypeIdentity<T>{});
}

// ์‚ฌ์šฉ ์˜ˆ
smartProcess(10);  // ์ •์ˆ˜ ์ฒ˜๋ฆฌ: 20
smartProcess(3.14);  // ์‹ค์ˆ˜ ์ฒ˜๋ฆฌ: 1.57
smartProcess(std::string("Hello"));  // ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ: Hello!

์šฐ์™€, ์ด๊ฑด ๋ญ”๊ฐ€ ๋ณต์žกํ•ด ๋ณด์ด์ฃ ? ๐Ÿ˜… ํ•˜์ง€๋งŒ ์ฒœ์ฒœํžˆ ์‚ดํŽด๋ณด๋ฉด ๊ทธ๋ ‡๊ฒŒ ์–ด๋ ต์ง€ ์•Š์•„์š”!

์ด ์ฝ”๋“œ๋Š” ์ž…๋ ฅ๋œ ๊ฐ’์˜ ํƒ€์ž…์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค˜์š”. ์ •์ˆ˜๋ฉด 2๋ฅผ ๊ณฑํ•˜๊ณ , ์‹ค์ˆ˜๋ฉด 2๋กœ ๋‚˜๋ˆ„๊ณ , ๋ฌธ์ž์—ด์ด๋ฉด ๋์— ๋Š๋‚Œํ‘œ๋ฅผ ๋ถ™์—ฌ์š”. ๋งˆ์น˜ ๋˜‘๋˜‘ํ•œ ๋น„์„œ๊ฐ€ ์ƒํ™ฉ์— ๋งž๊ฒŒ ์ผ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ๐Ÿ‘จโ€๐Ÿ’ผ

์ด๋Ÿฐ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ์˜ ์œ ์—ฐ์„ฑ์ด ํฌ๊ฒŒ ๋†’์•„์ ธ์š”. ์ƒˆ๋กœ์šด ํƒ€์ž…์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ๊ทธ๋ƒฅ ์ƒˆ๋กœ์šด process ํ•จ์ˆ˜๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ๋˜๋‹ˆ๊นŒ์š”!

๐Ÿงฉ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ์ด์šฉํ•œ ํŠœํ”Œ ๋งŒ๋“ค๊ธฐ

์ด์ œ ์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์šด ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ํ™œ์šฉํ•ด์„œ ๋ญ”๊ฐ€ ์ •๋ง ๋ฉ‹์ง„ ๊ฑธ ๋งŒ๋“ค์–ด๋ณผ๊นŒ์š”? ๋ฐ”๋กœ 'ํŠœํ”Œ'์ด์—์š”! ํŠœํ”Œ์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ํƒ€์ž…์˜ ๊ฐ’์„ ํ•˜๋‚˜๋กœ ๋ฌถ์–ด์ฃผ๋Š” ์ž๋ฃŒ๊ตฌ์กฐ์˜ˆ์š”. ๋งˆ์น˜ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ง›์ด ๋“ค์–ด์žˆ๋Š” ์•„์ด์Šคํฌ๋ฆผ ๊ฐ™์€ ๊ฑฐ์ฃ ! ๐Ÿฆ


template <typename... Types>
class Tuple;

template <>
class Tuple<> {};

template <typename Head, typename... Tail>
class Tuple<Head, Tail...> : private Tuple<Tail...> {
    Head head;
public:
    Tuple(Head h, Tail... tail) : Tuple<Tail...>(tail...), head(h) {}

    Head getHead() { return head; }
    Tuple<Tail...>& getTail() { return *this; }
};

// ์‚ฌ์šฉ ์˜ˆ
Tuple<int, double, std::string> myTuple(1, 3.14, "Hello");
std::cout << myTuple.getHead() << std::endl;  // 1
std::cout << myTuple.getTail().getHead() << std::endl;  // 3.14
std::cout << myTuple.getTail().getTail().getHead() << std::endl;  // Hello

์šฐ์™€! ์ด๊ฑด ์ •๋ง ๋Œ€๋‹จํ•ด ๋ณด์ด์ฃ ? ๐Ÿ˜ฎ ํ•˜์ง€๋งŒ ๊ฒ๋จน์ง€ ๋งˆ์„ธ์š”. ํ•˜๋‚˜์”ฉ ๋œฏ์–ด๋ณด๋ฉด ๊ทธ๋ ‡๊ฒŒ ์–ด๋ ต์ง€ ์•Š์•„์š”!

์ด ์ฝ”๋“œ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ํƒ€์ž…์˜ ๊ฐ’์„ ํ•˜๋‚˜๋กœ ๋ฌถ์–ด์ฃผ๋Š” ํŠœํ”Œ์„ ๋งŒ๋“ค์–ด์š”. ๋งˆ์น˜ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์žฌ๋ฃŒ๋ฅผ ํ•˜๋‚˜์˜ ๋„์‹œ๋ฝ์— ๋‹ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ๐Ÿฑ

์ด๋ ‡๊ฒŒ ๋งŒ๋“  ํŠœํ”Œ์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ํƒ€์ž…์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ•จ๊ป˜ ๋‹ค๋ฃฐ ๋•Œ ์•„์ฃผ ์œ ์šฉํ•ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž์˜ ์ด๋ฆ„(๋ฌธ์ž์—ด), ๋‚˜์ด(์ •์ˆ˜), ํ‚ค(์‹ค์ˆ˜)๋ฅผ ํ•œ ๋ฒˆ์— ์ €์žฅํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ฃ .

์ด๋Ÿฐ ๊ธฐ๋Šฅ์€ ์‹ค์ œ๋กœ ๋งŽ์ด ์“ฐ์—ฌ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ๋Šฅ๋„ท์—์„œ ์‚ฌ์šฉ์ž์˜ ๋‹ค์–‘ํ•œ ์ •๋ณด(์ด๋ฆ„, ๋‚˜์ด, ๋ณด์œ  ์žฌ๋Šฅ ๋“ฑ)๋ฅผ ํ•œ ๋ฒˆ์— ๊ด€๋ฆฌํ•  ๋•Œ ์ด๋Ÿฐ ํŠœํ”Œ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ ?

๐ŸŽจ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ์ด์šฉํ•œ ํŒฉํ† ๋ฆฌ ํŒจํ„ด

์ž, ์ด์ œ ์šฐ๋ฆฌ์˜ ์ง€์‹์„ ํ™œ์šฉํ•ด์„œ ์กฐ๊ธˆ ๋” ์‹ค์šฉ์ ์ธ ๊ฑธ ๋งŒ๋“ค์–ด๋ณผ๊นŒ์š”? ๋ฐ”๋กœ 'ํŒฉํ† ๋ฆฌ ํŒจํ„ด'์ด์—์š”. ํŒฉํ† ๋ฆฌ ํŒจํ„ด์€ ๊ฐ์ฒด ์ƒ์„ฑ์„ ์บก์Šํ™”ํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด์ธ๋ฐ, ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ์ด์šฉํ•˜๋ฉด ์•„์ฃผ ๋ฉ‹์ง€๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์–ด์š”! ๐Ÿ˜Ž


// ๊ธฐ๋ณธ ๋„ํ˜• ํด๋ž˜์Šค
class Shape {
public:
    virtual void draw() = 0;
    virtual ~Shape() {}
};

// ๊ตฌ์ฒด์ ์ธ ๋„ํ˜• ํด๋ž˜์Šค๋“ค
class Circle : public Shape {
public:
    void draw() override { std::cout << "Drawing a circle" << std::endl; }
};

class Square : public Shape {
public:
    void draw() override { std::cout << "Drawing a square" << std::endl; }
};

class Triangle : public Shape {
public:
    void draw() override { std::cout << "Drawing a triangle" << std::endl; }
};

// ํŒฉํ† ๋ฆฌ ํด๋ž˜์Šค
template <typename... Types>
class ShapeFactory {
    template <typename T>
    static Shape* createShape() { return new T(); }

    using FuncPtr = Shape* (*)();
    std::unordered_map<std::string, FuncPtr> m_factoryFunctions;

    template <typename T>
    void registerType(const std::string& key) {
        m_factoryFunctions[key] = &createShape<T>;
    }

    template <typename First, typename... Rest>
    void registerTypes(const std::string& firstKey, const std::string&... restKeys) {
        registerType<First>(firstKey);
        if constexpr (sizeof...(Rest) > 0) {
            registerTypes<Rest...>(restKeys...);
        }
    }

public:
    ShapeFactory(const std::string&... keys) {
        registerTypes<Types...>(keys...);
    }

    Shape* create(const std::string& key) {
        auto it = m_factoryFunctions.find(key);
        if (it != m_factoryF  unctions.end()) {
            return it->second();
        }
        return nullptr;
    }
};

// ์‚ฌ์šฉ ์˜ˆ
int main() {
    ShapeFactory<circle square triangle> factory("circle", "square", "triangle");

    Shape* circle = factory.create("circle");
    Shape* square = factory.create("square");
    Shape* triangle = factory.create("triangle");

    if (circle) circle->draw();
    if (square) square->draw();
    if (triangle) triangle->draw();

    delete circle;
    delete square;
    delete triangle;

    return 0;
}
</circle>

์šฐ์™€! ์ด๊ฑด ์ •๋ง ๋Œ€๋‹จํ•ด ๋ณด์ด์ฃ ? ๐Ÿ˜ฎ ํ•˜์ง€๋งŒ ๊ฑฑ์ • ๋งˆ์„ธ์š”. ์ฒœ์ฒœํžˆ ์„ค๋ช…ํ•ด๋“œ๋ฆด๊ฒŒ์š”!

์ด ์ฝ”๋“œ๋Š” 'ํŒฉํ† ๋ฆฌ ํŒจํ„ด'์ด๋ผ๋Š” ๋””์ž์ธ ํŒจํ„ด์„ ๊ตฌํ˜„ํ•œ ๊ฑฐ์˜ˆ์š”. ํŒฉํ† ๋ฆฌ ํŒจํ„ด์€ ๊ฐ์ฒด ์ƒ์„ฑ์„ ์บก์Šํ™”ํ•˜๋Š” ํŒจํ„ด์ธ๋ฐ, ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด "์ฃผ๋ฌธ์„œ"๊ฐ™์€ ๊ฑฐ์˜ˆ์š”. ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๋„ํ˜•์˜ ์ด๋ฆ„๋งŒ ๋งํ•˜๋ฉด, ํŒฉํ† ๋ฆฌ๊ฐ€ ์•Œ์•„์„œ ๊ทธ ๋„ํ˜•์„ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฑฐ์ฃ !

์ด ํŒฉํ† ๋ฆฌ ํด๋ž˜์Šค๋Š” ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์—ฌ๋Ÿฌ ์ข…๋ฅ˜์˜ ๋„ํ˜•์„ ํ•œ ๋ฒˆ์— ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์š”๋ฆฌ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋งŒ๋Šฅ ์ฃผ๋ฐฉ์žฅ ๊ฐ™์€ ๊ฑฐ์ฃ ! ๐Ÿ‘จโ€๐Ÿณ

์ด๋Ÿฐ ๋ฐฉ์‹์˜ ์žฅ์ ์€ ๋ญ˜๊นŒ์š”?

  1. ์œ ์—ฐ์„ฑ: ์ƒˆ๋กœ์šด ๋„ํ˜•์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ๊ทธ๋ƒฅ ์ƒˆ๋กœ์šด ๋„ํ˜• ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ  ํŒฉํ† ๋ฆฌ์— ๋“ฑ๋กํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ผ์š”. ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ๊ฑฐ์˜ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š์•„๋„ ๋˜์ฃ !
  2. ์บก์Šํ™”: ๊ฐ์ฒด ์ƒ์„ฑ ๋กœ์ง์ด ํ•œ ๊ณณ์— ๋ชจ์—ฌ์žˆ์–ด์„œ ์ฝ”๋“œ ๊ด€๋ฆฌ๊ฐ€ ์‰ฌ์›Œ์ ธ์š”.
  3. ํƒ€์ž… ์•ˆ์ „์„ฑ: ์ปดํŒŒ์ผ ์‹œ์ ์— ํƒ€์ž… ์ฒดํฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ์–ด์„œ ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์–ด์š”.

์ด๋Ÿฐ ํŒจํ„ด์€ ์‹ค์ œ๋กœ ๋งŽ์ด ์‚ฌ์šฉ๋ผ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ๋Šฅ๋„ท์—์„œ ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ์žฌ๋Šฅ์„ ๋“ฑ๋กํ•˜๊ณ  ๊ด€๋ฆฌํ•  ๋•Œ ์ด๋Ÿฐ ํŒฉํ† ๋ฆฌ ํŒจํ„ด์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ ? ๊ฐ ์žฌ๋Šฅ ์œ ํ˜•์„ ํ•˜๋‚˜์˜ '๋„ํ˜•'์ฒ˜๋Ÿผ ์ƒ๊ฐํ•˜๋ฉด ๋ผ์š”!

๐Ÿงฎ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ์ด์šฉํ•œ ์ปดํŒŒ์ผ ํƒ€์ž„ ๊ณ„์‚ฐ

์ž, ์ด์ œ ์ •๋ง ๋ฉ‹์ง„ ๊ฑธ ๋ณด์—ฌ๋“œ๋ฆด๊ฒŒ์š”! ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ์ด์šฉํ•˜๋ฉด ์ปดํŒŒ์ผ ํƒ€์ž„์— ๊ณ„์‚ฐ์„ ํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋ญ”๊ฐ€ ๋ณต์žกํ•ด ๋ณด์ด์ง€๋งŒ, ์‹ค์ œ๋กœ๋Š” ์•„์ฃผ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์ด์—์š”. ํ•œ๋ฒˆ ํŒฉํ† ๋ฆฌ์–ผ(๊ณ„์Šน) ๊ณ„์‚ฐ์„ ์˜ˆ๋กœ ๋“ค์–ด๋ณผ๊ฒŒ์š”!


template <unsigned N>
struct Factorial {
    static constexpr unsigned value = N * Factorial<N - 1>::value;
};

template <>
struct Factorial<0> {
    static constexpr unsigned value = 1;
};

template <unsigned... Ns>
struct FactorialList {
    static void print() {
        (std::cout << Factorial<Ns>::value << " ", ...);
        std::cout << std::endl;
    }
};

// ์‚ฌ์šฉ ์˜ˆ
int main() {
    FactorialList<0, 1, 2, 3, 4, 5>::print();
    return 0;
}

์ด ์ฝ”๋“œ๊ฐ€ ํ•˜๋Š” ์ผ์ด ๋ญ˜๊นŒ์š”? ๐Ÿ˜ƒ

์ด ์ฝ”๋“œ๋Š” ์ปดํŒŒ์ผ ํƒ€์ž„์— ํŒฉํ† ๋ฆฌ์–ผ ๊ฐ’์„ ๊ณ„์‚ฐํ•ด์š”. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•˜์ฃ . 0๋ถ€ํ„ฐ 5๊นŒ์ง€์˜ ํŒฉํ† ๋ฆฌ์–ผ ๊ฐ’์ด ํ•œ ๋ฒˆ์— ๊ณ„์‚ฐ๋˜์–ด ์ถœ๋ ฅ๋ผ์š”!

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋  ๋•Œ๊ฐ€ ์•„๋‹ˆ๋ผ ์ปดํŒŒ์ผ๋  ๋•Œ ๊ณ„์‚ฐ์ด ์ด๋ฃจ์–ด์ ธ์š”. ์‹คํ–‰ ์‹œ๊ฐ„์„ ๋‹จ์ถ•์‹œํ‚ฌ ์ˆ˜ ์žˆ์ฃ !

์ด๋Ÿฐ ๊ธฐ์ˆ ์€ ์„ฑ๋Šฅ์ด ์ค‘์š”ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋ผ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ๋Šฅ๋„ท์—์„œ ๋ณต์žกํ•œ ๋งค์นญ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ผ๋ถ€๋ฅผ ์ปดํŒŒ์ผ ํƒ€์ž„์— ๋ฏธ๋ฆฌ ๊ณ„์‚ฐํ•ด ๋†“์„ ์ˆ˜ ์žˆ๊ฒ ์ฃ ?

๐ŸŽญ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ์ด์šฉํ•œ ๋‹ค์ค‘ ์ƒ์†

๋งˆ์ง€๋ง‰์œผ๋กœ, ํƒ€์ž… ๋ฆฌ์ŠคํŠธ๋ฅผ ์ด์šฉํ•ด ๋‹ค์ค‘ ์ƒ์†์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ๋“œ๋ฆด๊ฒŒ์š”. ์ด๊ฑด ์ •๋ง ๊ณ ๊ธ‰ ๊ธฐ์ˆ ์ด์—์š”! ๐Ÿ˜Ž


template <typename... Bases>
struct Inherit : Bases... {
    Inherit(const Bases&... bases) : Bases(bases)... {}
};

// ์‚ฌ์šฉ ์˜ˆ
struct A { void foo() { std::cout << "A::foo" << std::endl; } };
struct B { void bar() { std::cout << "B::bar" << std::endl; } };
struct C { void baz() { std::cout << "C::baz" << std::endl; } };

int main() {
    Inherit<A, B, C> obj(A{}, B{}, C{});
    obj.foo();
    obj.bar();
    obj.baz();
    return 0;
}

์ด ์ฝ”๋“œ๋Š” ๋ญ˜ ํ•˜๋Š” ๊ฑธ๊นŒ์š”? ๐Ÿค”

์ด ์ฝ”๋“œ๋Š” ์—ฌ๋Ÿฌ ํด๋ž˜์Šค๋ฅผ ํ•œ ๋ฒˆ์— ์ƒ์†๋ฐ›๋Š” ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์š”. ๋งˆ์น˜ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋Šฅ๋ ฅ์„ ๊ฐ€์ง„ ์Šˆํผํžˆ์–ด๋กœ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ ๊ฐ™์ฃ ? ใ…‹ใ…‹ใ…‹

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์—ฌ๋Ÿฌ ํด๋ž˜์Šค์˜ ๊ธฐ๋Šฅ์„ ํ•œ ๋ฒˆ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์„ฑ์ด ๋†’์•„์ง€์ฃ !

์ด๋Ÿฐ ๊ธฐ์ˆ ์€ ๋ณต์žกํ•œ ์‹œ์Šคํ…œ์„ ์„ค๊ณ„ํ•  ๋•Œ ์œ ์šฉํ•ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ๋Šฅ๋„ท์—์„œ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ(ํ”„๋กœํ•„ ๊ด€๋ฆฌ, ๊ฒฐ์ œ ์‹œ์Šคํ…œ, ๋ฉ”์‹œ์ง• ๋“ฑ)์„ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ ์ด๋Ÿฐ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ ?

๐ŸŽ‰ ๋งˆ๋ฌด๋ฆฌ

์ž, ์—ฌ๊ธฐ๊นŒ์ง€ ํƒ€์ž… ๋ฆฌ์ŠคํŠธ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„์— ๋Œ€ํ•ด ์•Œ์•„๋ดค์–ด์š”. ์–ด๋– ์…จ๋‚˜์š”? ์ฒ˜์Œ์—๋Š” ์–ด๋ ค์›Œ ๋ณด์˜€์ง€๋งŒ, ํ•˜๋‚˜์”ฉ ๋œฏ์–ด๋ณด๋‹ˆ ๊ทธ๋ ‡๊ฒŒ ๋ฌด์„œ์šด ๊ฒŒ ์•„๋‹ˆ์—ˆ์ฃ ? ๐Ÿ˜‰

์ด๋Ÿฐ ๊ณ ๊ธ‰ C++ ๊ธฐ์ˆ ๋“ค์€ ์ฒ˜์Œ์—๋Š” ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์–ด์š”. ํ•˜์ง€๋งŒ ์กฐ๊ธˆ์”ฉ ์—ฐ์Šตํ•˜๋‹ค ๋ณด๋ฉด, ์—ฌ๋Ÿฌ๋ถ„๋„ ์ถฉ๋ถ„ํžˆ ๋งˆ์Šคํ„ฐํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”! ๐Ÿ’ช

๊ธฐ์–ตํ•˜์„ธ์š”, ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ๋‹จ์ˆœํžˆ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฑฐ์˜ˆ์š”. ํƒ€์ž… ๋ฆฌ์ŠคํŠธ์™€ ๊ฐ™์€ ๊ณ ๊ธ‰ ๊ธฐ์ˆ ์€ ์—ฌ๋Ÿฌ๋ถ„์ด ๋” ํšจ์œจ์ ์œผ๋กœ, ๋” ์šฐ์•„ํ•˜๊ฒŒ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ๋„๊ตฌ์ผ ๋ฟ์ด์—์š”.

์—ฌ๋Ÿฌ๋ถ„๋„ ์ด์ œ ์ด๋Ÿฐ ๊ธฐ์ˆ ๋“ค์„ ํ™œ์šฉํ•ด์„œ ๋ฉ‹์ง„ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค์–ด๋ณด์„ธ์š”! ๋งˆ์น˜ ์žฌ๋Šฅ๋„ท์—์„œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์žฌ๋Šฅ์„ ๋ฝ๋‚ด๋“ฏ์ด, C++์—์„œ๋„ ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์‹ค๋ ฅ์„ ๋ฝ๋‚ด๋ณด์„ธ์š”! ๐ŸŒŸ

์ฝ”๋”ฉ์€ ์žฌ๋ฏธ์žˆ์–ด์š”. ์–ด๋ ค์šธ ๋•Œ๋„ ์žˆ์ง€๋งŒ, ๊ทธ ์–ด๋ ค์›€์„ ๊ทน๋ณตํ•˜๊ณ  ๋‚˜๋ฉด ์ •๋ง ํฐ ์„ฑ์ทจ๊ฐ์„ ๋Š๋‚„ ์ˆ˜ ์žˆ์ฃ . ์—ฌ๋Ÿฌ๋ถ„์˜ C++ ์—ฌ์ •์„ ์‘์›ํ•ฉ๋‹ˆ๋‹ค! ํ™”์ดํŒ…! ๐Ÿ’ป๐Ÿš€