๐Ÿš€ ํƒ€์ž… ํŠน์„ฑ(Type Traits)๊ณผ SFINAE: C++ ๋งˆ๋ฒ•์‚ฌ์˜ ๋น„๋ฐ€ ๋„๊ตฌ ์ƒ์ž ๐Ÿง™โ€โ™‚๏ธ

์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿš€ ํƒ€์ž… ํŠน์„ฑ(Type Traits)๊ณผ SFINAE: C++ ๋งˆ๋ฒ•์‚ฌ์˜ ๋น„๋ฐ€ ๋„๊ตฌ ์ƒ์ž ๐Ÿง™โ€โ™‚๏ธ

 

 

์•ˆ๋…•ํ•˜์„ธ์š”, C++ ๊ฐœ๋ฐœ์ž ์—ฌ๋Ÿฌ๋ถ„! ์˜ค๋Š˜์€ ์ •๋ง ํฅ๋ฏธ์ง„์ง„ํ•œ ์ฃผ์ œ๋กœ ์—ฌ๋Ÿฌ๋ถ„๊ณผ ํ•จ๊ป˜ ์ด์•ผ๊ธฐ๋ฅผ ๋‚˜๋ˆ ๋ณผ๊นŒ ํ•ด์š”. ๋ฐ”๋กœ "ํƒ€์ž… ํŠน์„ฑ(Type Traits)"๊ณผ "SFINAE"๋ผ๋Š” C++์˜ ๋งˆ๋ฒ• ๊ฐ™์€ ๊ธฐ๋Šฅ๋“ค์ด์—์š”. ใ…‹ใ…‹ใ…‹ ์ด๋ฆ„๋ถ€ํ„ฐ ๋ญ”๊ฐ€ ์–ด๋ ค์›Œ ๋ณด์ด์ฃ ? ๊ฑฑ์ • ๋งˆ์„ธ์š”! ์ œ๊ฐ€ ์‰ฝ๊ณ  ์žฌ๋ฏธ์žˆ๊ฒŒ ์„ค๋ช…ํ•ด๋“œ๋ฆด๊ฒŒ์š”. ๋งˆ์น˜ ์นดํ†ก์œผ๋กœ ์ˆ˜๋‹ค ๋– ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ๐Ÿ˜‰

์ด ๊ธ€์€ ์žฌ๋Šฅ๋„ท(https://www.jaenung.net)์˜ '์ง€์‹์ธ์˜ ์ˆฒ' ๋ฉ”๋‰ด์— ๋“ฑ๋ก๋  ์˜ˆ์ •์ด์—์š”. ์žฌ๋Šฅ๋„ท์€ ๋‹ค์–‘ํ•œ ์žฌ๋Šฅ์„ ๊ณต์œ ํ•˜๊ณ  ๊ฑฐ๋ž˜ํ•˜๋Š” ํ”Œ๋žซํผ์ธ๋ฐ, C++ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์‹ค๋ ฅ๋„ ๋ฉ‹์ง„ ์žฌ๋Šฅ ์ค‘ ํ•˜๋‚˜์ฃ ! ์ด ๊ธ€์„ ํ†ตํ•ด ์—ฌ๋Ÿฌ๋ถ„์˜ C++ ์žฌ๋Šฅ์ด ํ•œ์ธต ๋” ์—…๊ทธ๋ ˆ์ด๋“œ๋  ๊ฑฐ์˜ˆ์š”. ์ž, ๊ทธ๋Ÿผ ์‹œ์ž‘ํ•ด๋ณผ๊นŒ์š”? ๐ŸŽ‰

๐Ÿ” ์˜ค๋Š˜์˜ ํ•™์Šต ๋ชฉํ‘œ:

  • ํƒ€์ž… ํŠน์„ฑ(Type Traits)์˜ ๊ฐœ๋…๊ณผ ์‚ฌ์šฉ๋ฒ• ์ดํ•ดํ•˜๊ธฐ
  • SFINAE์˜ ์›๋ฆฌ์™€ ํ™œ์šฉ ๋ฐฉ๋ฒ• ์ตํžˆ๊ธฐ
  • ์‹ค์ œ ์ฝ”๋“œ์—์„œ ์ด ๊ฐœ๋…๋“ค์„ ์–ด๋–ป๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๊ธฐ

์ž, ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ C++์˜ ๋งˆ๋ฒ• ์„ธ๊ณ„๋กœ ๋“ค์–ด๊ฐ€๋ณผ๊นŒ์š”? ๐Ÿง™โ€โ™‚๏ธโœจ

๐Ÿง ํƒ€์ž… ํŠน์„ฑ(Type Traits)์ด ๋ญ์•ผ? ์™œ ํ•„์š”ํ•ด?

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

ํƒ€์ž… ํŠน์„ฑ์€ C++์—์„œ ์ปดํŒŒ์ผ ํƒ€์ž„์— ํƒ€์ž…์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป๊ฑฐ๋‚˜ ํƒ€์ž…์„ ๋ณ€ํ˜•ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํ…œํ”Œ๋ฆฟ ํด๋ž˜์Šค๋“ค์˜ ๋ชจ์Œ์ด์—์š”. ์Œ... ๋ญ” ์†Œ๋ฆฌ๋ƒ๊ณ ์š”? ์‰ฝ๊ฒŒ ๋งํ•ด์„œ, ํƒ€์ž…์— ๋Œ€ํ•ด ์ด๊ฒƒ์ €๊ฒƒ ๋ฌผ์–ด๋ณด๊ณ  ํ•„์š”ํ•˜๋ฉด ์‚ด์ง ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋„๊ตฌ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋ผ์š”. ๐Ÿ‘€

๐Ÿ’ก ํƒ€์ž… ํŠน์„ฑ์˜ ์ฃผ์š” ๊ธฐ๋Šฅ:

  • ํƒ€์ž…์ด ์–ด๋–ค ํŠน์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ (์˜ˆ: ์ •์ˆ˜์ธ์ง€, ํฌ์ธํ„ฐ์ธ์ง€ ๋“ฑ)
  • ํƒ€์ž…์„ ๋ณ€ํ˜•ํ•˜๊ธฐ (์˜ˆ: const ์ œ๊ฑฐ, ์ฐธ์กฐ ์ œ๊ฑฐ ๋“ฑ)
  • ์กฐ๊ฑด๋ถ€ ํƒ€์ž… ์„ ํƒํ•˜๊ธฐ

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

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

๐ŸŽญ ํƒ€์ž… ํŠน์„ฑ์˜ ์ข…๋ฅ˜

ํƒ€์ž… ํŠน์„ฑ์—๋Š” ์ •๋ง ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜๊ฐ€ ์žˆ์–ด์š”. ๋งˆ์น˜ ์žฌ๋Šฅ๋„ท์— ๋‹ค์–‘ํ•œ ์žฌ๋Šฅ์ด ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ๋ช‡ ๊ฐ€์ง€ ๋Œ€ํ‘œ์ ์ธ ๊ฒƒ๋“ค์„ ์‚ดํŽด๋ณผ๊นŒ์š”?

  • is_integral: ์ •์ˆ˜ ํƒ€์ž…์ธ์ง€ ํ™•์ธํ•ด์š”.
  • is_floating_point: ๋ถ€๋™์†Œ์ˆ˜์  ํƒ€์ž…์ธ์ง€ ๋ด์š”.
  • is_pointer: ํฌ์ธํ„ฐ์ธ์ง€ ์•Œ๋ ค์ค˜์š”.
  • remove_const: const๋ฅผ ์ œ๊ฑฐํ•ด์ค˜์š”.
  • remove_reference: ์ฐธ์กฐ๋ฅผ ์ œ๊ฑฐํ•ด์š”.
  • conditional: ์กฐ๊ฑด์— ๋”ฐ๋ผ ํƒ€์ž…์„ ์„ ํƒํ•ด์š”.

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

๐Ÿš€ ํƒ€์ž… ํŠน์„ฑ ์‚ฌ์šฉ ์˜ˆ์‹œ

์ž, ์ด์ œ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€ ๋ณผ๊นŒ์š”? ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


#include <type_traits>
#include <iostream>

template <typename T>
void check_type(T value) {
    if (std::is_integral<T>::value) {
        std::cout << "์ด๊ฒƒ์€ ์ •์ˆ˜์ž…๋‹ˆ๋‹ค!" << std::endl;
    } else if (std::is_floating_point<T>::value) {
        std::cout << "์ด๊ฒƒ์€ ๋ถ€๋™์†Œ์ˆ˜์  ์ˆซ์ž์ž…๋‹ˆ๋‹ค!" << std::endl;
    } else {
        std::cout << "์ด๊ฒƒ์€... ์Œ... ๋ญ”๊ฐ€ ๋‹ค๋ฅธ ๊ฑฐ์˜ˆ์š”!" << std::endl;
    }
}

int main() {
    check_type(42);        // ์ •์ˆ˜
    check_type(3.14);      // ๋ถ€๋™์†Œ์ˆ˜์ 
    check_type("Hello");   // ๋ฌธ์ž์—ด
    return 0;
}

์ด ์ฝ”๋“œ์—์„œ std::is_integral๊ณผ std::is_floating_point๋Š” ํƒ€์ž… ํŠน์„ฑ์ด์—์š”. ์ด๋“ค์€ ์ฃผ์–ด์ง„ ํƒ€์ž… T๊ฐ€ ๊ฐ๊ฐ ์ •์ˆ˜์ธ์ง€, ๋ถ€๋™์†Œ์ˆ˜์  ์ˆซ์ž์ธ์ง€๋ฅผ ์•Œ๋ ค์ค๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํƒ€์ž… ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด, ์ปดํŒŒ์ผ ์‹œ์ ์— ํƒ€์ž…์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์–ด์š”. ์ด๋Š” ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ ์—†์ด ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ๋†’์ด๊ณ  ์ตœ์ ํ™”๋œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค๋‹ˆ๋‹ค.

๐ŸŽจ ์žฌ๋Šฅ๋„ท ํŒ: ํƒ€์ž… ํŠน์„ฑ์€ ๋งˆ์น˜ ์žฌ๋Šฅ๋„ท์—์„œ ๋‹ค์–‘ํ•œ ์žฌ๋Šฅ์„ ๋ถ„๋ฅ˜ํ•˜๊ณ  ์ฐพ๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•ด์š”. ์—ฌ๋Ÿฌ๋ถ„์ด ์›ํ•˜๋Š” ์žฌ๋Šฅ(ํƒ€์ž…)์„ ์ •ํ™•ํžˆ ์ฐพ์•„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ์ฃ . ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋„ ์ด๋Ÿฐ '์žฌ๋Šฅ ๋ถ„๋ฅ˜' ๋Šฅ๋ ฅ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค!

์ž, ์ด์ œ ํƒ€์ž… ํŠน์„ฑ์— ๋Œ€ํ•ด ์กฐ๊ธˆ์€ ์ดํ•ด๊ฐ€ ๋˜์…จ๋‚˜์š”? ใ…Žใ…Ž ์–ด๋ ค์›Œ ๋ณด์ด์ง€๋งŒ ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•ด๋ณด๋ฉด ์ •๋ง ์œ ์šฉํ•˜๋‹ต๋‹ˆ๋‹ค. ๋‹ค์Œ์œผ๋กœ๋Š” ๋” ์‹ ๊ธฐํ•œ ๊ฐœ๋…์ธ SFINAE์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ๊ฑฐ์˜ˆ์š”. ์ค€๋น„๋˜์…จ๋‚˜์š”? ๐Ÿš€

๐ŸŽญ SFINAE: C++์˜ ๋งˆ๋ฒ• ๊ฐ™์€ ๊ธฐ๋Šฅ

์ž, ์ด์ œ ์ •๋ง ์žฌ๋ฏธ์žˆ๋Š” ๋ถ€๋ถ„์ด ์™”์–ด์š”! SFINAE๋ผ๋Š” ๊ฑฐ ๋“ค์–ด๋ณด์…จ๋‚˜์š”? ๋ญ”๊ฐ€ ์–ด๋ ค์›Œ ๋ณด์ด๋Š” ์ด๋ฆ„์ด์ฃ ? ใ…‹ใ…‹ใ…‹ ๊ฑฑ์ • ๋งˆ์„ธ์š”, ์ œ๊ฐ€ ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•ด๋“œ๋ฆด๊ฒŒ์š”!

SFINAE๋Š” "Substitution Failure Is Not An Error"์˜ ์•ฝ์ž์˜ˆ์š”. ํ•œ๊ตญ์–ด๋กœ ํ•˜๋ฉด "์น˜ํ™˜ ์‹คํŒจ๋Š” ์˜ค๋ฅ˜๊ฐ€ ์•„๋‹ˆ๋‹ค"๋ผ๋Š” ๋œป์ด์ฃ . ์Œ... ๋ญ” ์†Œ๋ฆฌ๋ƒ๊ณ ์š”? ์‰ฝ๊ฒŒ ๋งํ•ด์„œ, C++ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ…œํ”Œ๋ฆฟ์„ ์ฒ˜๋ฆฌํ•  ๋•Œ "์ด๊ฑด ์•ˆ ๋˜๋„ค? ๊ทธ๋Ÿผ ๋‹ค๋ฅธ ๊ฑธ๋กœ ํ•ด๋ณผ๊ฒŒ~"๋ผ๊ณ  ํ•˜๋Š” ๊ฑฐ์˜ˆ์š”. ๊ท€์—ฌ์šด ์ปดํŒŒ์ผ๋Ÿฌ์ฃ ? ๐Ÿ˜Š

๐ŸŽˆ SFINAE์˜ ํ•ต์‹ฌ ๊ฐœ๋…:

  • ํ…œํ”Œ๋ฆฟ ์ธ์Šคํ„ด์Šคํ™” ๊ณผ์ •์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ด๋„ ๋ฐ”๋กœ ์ปดํŒŒ์ผ ์—๋Ÿฌ๋ฅผ ๋‚ด์ง€ ์•Š์•„์š”.
  • ๋Œ€์‹ , ๋‹ค๋ฅธ ๊ฐ€๋Šฅํ•œ ์˜ค๋ฒ„๋กœ๋“œ๋‚˜ ํŠน์ˆ˜ํ™”๋ฅผ ์ฐพ์•„๋ด์š”.
  • ์ด๋ฅผ ํ†ตํ•ด ์ปดํŒŒ์ผ ํƒ€์ž„์— ์กฐ๊ฑด๋ถ€๋กœ ํ•จ์ˆ˜๋‚˜ ํด๋ž˜์Šค๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ์–ด์š”.

SFINAE๋Š” ๋งˆ์น˜ ์žฌ๋Šฅ๋„ท์—์„œ ์—ฌ๋Ÿฌ๋ถ„์ด ์›ํ•˜๋Š” ์žฌ๋Šฅ์„ ๊ฐ€์ง„ ์‚ฌ๋žŒ์„ ์ฐพ๋Š” ๊ณผ์ •๊ณผ ๋น„์Šทํ•ด์š”. ์ฒ˜์Œ์— ์ฐพ์€ ์‚ฌ๋žŒ์ด ์กฐ๊ฑด์— ๋งž์ง€ ์•Š์œผ๋ฉด, ๋‹ค๋ฅธ ์‚ฌ๋žŒ์„ ์ฐพ์•„๋ณด๋Š” ๊ฑฐ์ฃ . ์ปดํŒŒ์ผ๋Ÿฌ๋„ ์ด๋ ‡๊ฒŒ "์ด ํ…œํ”Œ๋ฆฟ์€ ์•ˆ ๋˜๋„ค? ๊ทธ๋Ÿผ ๋‹ค๋ฅธ ๊ฑธ๋กœ~"ํ•˜๋ฉด์„œ ์ตœ์ ์˜ ํ•จ์ˆ˜๋‚˜ ํด๋ž˜์Šค๋ฅผ ์ฐพ์•„๊ฐ€๋Š” ๊ฑฐ์˜ˆ์š”. ๐Ÿ˜„

๐Ÿงฉ SFINAE๋Š” ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ• ๊นŒ?

SFINAE์˜ ์ž‘๋™ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด, ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋ฅผ ์‚ดํŽด๋ณผ๊ฒŒ์š”.


#include <iostream>
#include <type_traits>

// ์ •์ˆ˜ ํƒ€์ž…์„ ์œ„ํ•œ ํ•จ์ˆ˜
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
void print_number(T value) {
    std::cout << "์ด๊ฒƒ์€ ์ •์ˆ˜์˜ˆ์š”: " << value << std::endl;
}

// ๋ถ€๋™์†Œ์ˆ˜์  ํƒ€์ž…์„ ์œ„ํ•œ ํ•จ์ˆ˜
template <typename T, typename = std::enable_if_t<std::is_floating_point<T>::value>>
void print_number(T value) {
    std::cout << "์ด๊ฒƒ์€ ๋ถ€๋™์†Œ์ˆ˜์  ์ˆซ์ž์˜ˆ์š”: " << value << std::endl;
}

int main() {
    print_number(42);    // ์ •์ˆ˜ ๋ฒ„์ „ ํ˜ธ์ถœ
    print_number(3.14);  // ๋ถ€๋™์†Œ์ˆ˜์  ๋ฒ„์ „ ํ˜ธ์ถœ
    return 0;
}

์ด ์ฝ”๋“œ์—์„œ std::enable_if_t์™€ ํƒ€์ž… ํŠน์„ฑ์„ ์‚ฌ์šฉํ•ด SFINAE๋ฅผ ๊ตฌํ˜„ํ–ˆ์–ด์š”. ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๊ฐ print_number ํ•จ์ˆ˜ ํ…œํ”Œ๋ฆฟ์„ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜์ง€๋งŒ, ์กฐ๊ฑด์— ๋งž์ง€ ์•Š์œผ๋ฉด ๊ทธ ํ…œํ”Œ๋ฆฟ์„ ๋ฌด์‹œํ•˜๊ณ  ๋‹ค์Œ ๊ฒƒ์„ ์‹œ๋„ํ•ด์š”.

์ด๋ ‡๊ฒŒ SFINAE๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ์ปดํŒŒ์ผ ํƒ€์ž„์— ํƒ€์ž…์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๋Š” ์ฝ”๋“œ์˜ ์œ ์—ฐ์„ฑ๊ณผ ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ํฌ๊ฒŒ ๋†’์—ฌ์ค๋‹ˆ๋‹ค.

๐ŸŽจ SFINAE์˜ ์‹ค์ œ ํ™œ์šฉ

SFINAE๋Š” ๋‹จ์ˆœํžˆ "์ด๋Ÿฐ ๊ฒŒ ์žˆ์–ด์š”~" ํ•˜๊ณ  ๋๋‚˜๋Š” ๊ฐœ๋…์ด ์•„๋‹ˆ์—์š”. ์‹ค์ œ๋กœ ๋งŽ์€ ๊ณณ์—์„œ ์œ ์šฉํ•˜๊ฒŒ ์“ฐ์ด๊ณ  ์žˆ์ฃ . ๋ช‡ ๊ฐ€์ง€ ์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊ฒŒ์š”:

  1. ํƒ€์ž…์— ๋”ฐ๋ฅธ ์ตœ์ ํ™”: ํŠน์ • ํƒ€์ž…์— ๋Œ€ํ•ด ๋” ํšจ์œจ์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์–ด์š”.
  2. ์ธํ„ฐํŽ˜์ด์Šค ์ฒดํฌ: ํด๋ž˜์Šค๊ฐ€ ํŠน์ • ๋ฉ”์„œ๋“œ๋‚˜ ํƒ€์ž…์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ์ปดํŒŒ์ผ ํƒ€์ž„์— ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.
  3. ์ œ์•ฝ ์กฐ๊ฑด ๊ตฌํ˜„: ํ…œํ”Œ๋ฆฟ ํŒŒ๋ผ๋ฏธํ„ฐ์— ์ œ์•ฝ์„ ๊ฑธ์–ด ์˜๋„ํ•˜์ง€ ์•Š์€ ํƒ€์ž…์˜ ์‚ฌ์šฉ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์–ด์š”.
  4. ํƒœ๊ทธ ๋””์ŠคํŒจ์น˜: ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ ์—†์ด ๋‹ค์–‘ํ•œ ํƒ€์ž…์— ๋Œ€ํ•œ ํŠน์ˆ˜ํ™”๋œ ๊ตฌํ˜„์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์–ด์š”.

์žฌ๋Šฅ๋„ท์—์„œ ๋‹ค์–‘ํ•œ ์žฌ๋Šฅ์„ ๊ฐ€์ง„ ์‚ฌ๋žŒ๋“ค์„ ์ฐพ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, SFINAE๋Š” ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” "์žฌ๋Šฅ(๊ธฐ๋Šฅ)"์„ ๊ฐ€์ง„ ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผ ํƒ€์ž„์— ์ฐพ์•„๋‚ด๋Š” ๊ฑฐ์˜ˆ์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋Ÿฐํƒ€์ž„์— ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ค๋ฅ˜๋ฅผ ๋ฏธ๋ฆฌ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์ฃ . ๐Ÿ‘

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

์ž, ์ด์ œ SFINAE์— ๋Œ€ํ•ด ์กฐ๊ธˆ์€ ๊ฐ์ด ์˜ค์‹œ๋‚˜์š”? ใ…Žใ…Ž ์ฒ˜์Œ์—๋Š” ์–ด๋ ค์›Œ ๋ณด์ด์ง€๋งŒ, ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•ด๋ณด๋ฉด ์ •๋ง ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๋ผ๋Š” ๊ฑธ ๋Š๋ผ์‹ค ๊ฑฐ์˜ˆ์š”. ๋‹ค์Œ์œผ๋กœ๋Š” ํƒ€์ž… ํŠน์„ฑ๊ณผ SFINAE๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ๊ฑฐ์˜ˆ์š”. ์ค€๋น„๋˜์…จ๋‚˜์š”? Let's go! ๐Ÿš€

๐Ÿ”ฎ ํƒ€์ž… ํŠน์„ฑ๊ณผ SFINAE์˜ ํ™˜์ƒ์ ์ธ ์ฝœ๋ผ๋ณด

์ž, ์ด์ œ ์ •๋ง ์žฌ๋ฏธ์žˆ๋Š” ๋ถ€๋ถ„์ด ์™”์–ด์š”! ํƒ€์ž… ํŠน์„ฑ๊ณผ SFINAE๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ค ๋งˆ๋ฒ•์ด ์ผ์–ด๋‚ ๊นŒ์š”? ๐Ÿง™โ€โ™‚๏ธโœจ ์ด ๋‘ ๊ฐ€์ง€๋ฅผ ๊ฒฐํ•ฉํ•˜๋ฉด, C++์—์„œ ์ •๋ง ๊ฐ•๋ ฅํ•˜๊ณ  ์œ ์—ฐํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ์žฌ๋Šฅ๋„ท์—์„œ ์—ฌ๋Ÿฌ ์žฌ๋Šฅ์„ ๊ฐ€์ง„ ์Šˆํผ ์ธ์žฌ๋ฅผ ์ฐพ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์ฃ ! ๐Ÿ˜‰

๐ŸŽญ ํƒ€์ž… ํŠน์„ฑ + SFINAE = ์ฝ”๋“œ์˜ ๋งˆ๋ฒ•

ํƒ€์ž… ํŠน์„ฑ๊ณผ SFINAE๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด, ์ปดํŒŒ์ผ ํƒ€์ž„์— ํƒ€์ž…์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋™์ž‘์„ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๊ฒŒ ๋ฌด์Šจ ๋ง์ด๋ƒ๊ณ ์š”? ์‰ฝ๊ฒŒ ๋งํ•ด์„œ, ์ฝ”๋“œ๊ฐ€ ์Šค์Šค๋กœ "์•„, ์ด ํƒ€์ž…์ด๊ตฌ๋‚˜! ๊ทธ๋Ÿผ ์ด๋ ‡๊ฒŒ ํ•ด์•ผ์ง€~"๋ผ๊ณ  ํŒ๋‹จํ•˜๊ณ  ํ–‰๋™ํ•˜๋Š” ๊ฑฐ์˜ˆ์š”. ๋˜‘๋˜‘ํ•˜์ฃ ? ใ…‹ใ…‹ใ…‹

์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊ฒŒ์š”:


#include <iostream>
#include <type_traits>

// ์ปจํ…Œ์ด๋„ˆ ํƒ€์ž…์„ ์œ„ํ•œ ํ•จ์ˆ˜
template <typename T, typename = std::enable_if_t<std::is_array<T>::value || std::is_class<T>::value>>
void process(const T& container) {
    std::cout << "์ด๊ฑด ์ปจํ…Œ์ด๋„ˆ์˜ˆ์š”! ์›์†Œ๋ฅผ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ์–ด์š”." << std::endl;
}

// ์‚ฐ์ˆ  ํƒ€์ž…์„ ์œ„ํ•œ ํ•จ์ˆ˜
template <typename T, typename = std::enable_if_t<std::is_arithmetic<T>::value>>
void process(T value) {
    std::cout << "์ด๊ฑด ์ˆซ์ž์˜ˆ์š”! ๊ฐ’์€ " << value << "์ž…๋‹ˆ๋‹ค." << std::endl;
}

int main() {
    int arr[] = {1, 2, 3};
    process(arr);  // ์ปจํ…Œ์ด๋„ˆ ๋ฒ„์ „ ํ˜ธ์ถœ
    process(42);   // ์‚ฐ์ˆ  ํƒ€์ž… ๋ฒ„์ „ ํ˜ธ์ถœ
    return 0;
}

์ด ์ฝ”๋“œ์—์„œ std::enable_if_t์™€ ์—ฌ๋Ÿฌ ํƒ€์ž… ํŠน์„ฑ(is_array, is_class, is_arithmetic)์„ ์‚ฌ์šฉํ•ด SFINAE๋ฅผ ๊ตฌํ˜„ํ–ˆ์–ด์š”. ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๊ฐ process ํ•จ์ˆ˜ ํ…œํ”Œ๋ฆฟ์„ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜์ง€๋งŒ, ์กฐ๊ฑด์— ๋งž์ง€ ์•Š์œผ๋ฉด ๊ทธ ํ…œํ”Œ๋ฆฟ์„ ๋ฌด์‹œํ•˜๊ณ  ๋‹ค์Œ ๊ฒƒ์„ ์‹œ๋„ํ•ด์š”.

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

๐Ÿš€ ๋” ๋ณต์žกํ•œ ์˜ˆ์ œ: ์™„๋ฒฝ ์ „๋‹ฌ๊ณผ SFINAE

์ด๋ฒˆ์—๋Š” ์กฐ๊ธˆ ๋” ๋ณต์žกํ•œ ์˜ˆ์ œ๋ฅผ ๋ณผ๊ฒŒ์š”. ์™„๋ฒฝ ์ „๋‹ฌ(Perfect Forwarding)๊ณผ SFINAE๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์˜ˆ์š”.


#include <iostream>
#include <type_traits>

// ์ด๋™ ๊ฐ€๋Šฅํ•œ ํƒ€์ž…์„ ์œ„ํ•œ ํ•จ์ˆ˜
template <typename T, typename = std::enable_if_t<std::is_move_constructible<T>::value>>
void process(T&& value) {
    std::cout << "์ด๋™ ์ƒ์„ฑ ๊ฐ€๋Šฅํ•œ ํƒ€์ž…์ด์—์š”!" << std::endl;
    // ์—ฌ๊ธฐ์„œ std::move๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”
}

// ์ด๋™ ๋ถˆ๊ฐ€๋Šฅํ•œ ํƒ€์ž…์„ ์œ„ํ•œ ํ•จ์ˆ˜
template <typename T, typename = std::enable_if_t<!std::is_move_constructible<T>::value>>
void process(const T& value) {
    std::cout << "์ด๋™ ์ƒ์„ฑ ๋ถˆ๊ฐ€๋Šฅํ•œ ํƒ€์ž…์ด์—์š”. ๋ณต์‚ฌ๋งŒ ๊ฐ€๋Šฅํ•ด์š”." << std::endl;
}

// ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ์ด๋™ ๋ถˆ๊ฐ€๋Šฅํ•œ ํด๋ž˜์Šค
class NonMovable {
public:
    NonMovable() = default;
    NonMovable(const NonMovable&) = default;
    NonMovable(NonMovable&&) = delete;
};

int main() {
    std::string str = "Hello";
    process(str);  // ์ด๋™ ๊ฐ€๋Šฅ

    NonMovable nm;
    process(nm);   // ์ด๋™ ๋ถˆ๊ฐ€๋Šฅ

    return 0;
}

์ด ์˜ˆ์ œ์—์„œ๋Š” std::is_move_constructible๋ฅผ ์‚ฌ์šฉํ•ด ํƒ€์ž…์ด ์ด๋™ ์ƒ์„ฑ ๊ฐ€๋Šฅํ•œ์ง€ ํ™•์ธํ•˜๊ณ , ๊ทธ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ์„ ํƒํ•ด์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํƒ€์ž…์˜ ํŠน์„ฑ์— ๋”ฐ๋ผ ์ตœ์ ํ™”๋œ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์ฃ .

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

๐ŸŽจ ์‹ค์ œ ์‚ฌ์šฉ ์‚ฌ๋ก€: ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ ๊ตฌํ˜„

ํƒ€์ž… ํŠน์„ฑ๊ณผ SFINAE์˜ ์กฐํ•ฉ์€ ์‹ค์ œ๋กœ ๋งŽ์€ ๊ณณ์—์„œ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์–ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, C++์˜ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ ๊ตฌํ˜„์—์„œ๋„ ์ด ๊ธฐ๋ฒ•์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ ์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊ฒŒ์š”:


#include <iostream>
#include <memory>
#include <type_traits>

template <typename T>
class SmartPtr {
    T* ptr;

public:
    template <typename U, typename = std::enable_if_t<std::is_convertible<U*, T*>::value>>
    SmartPtr(U* p) : ptr(p) {
        std::cout << "๋ณ€ํ™˜ ๊ฐ€๋Šฅํ•œ ํฌ์ธํ„ฐ๋กœ ์ƒ์„ฑ" << std::endl;
    }

    // ์‚ญ์ œ์ž๋ฅผ ๋ฐ›๋Š” ์ƒ์„ฑ์ž
    template <typename U, typename Deleter, 
              typename = std::enable_if_t<std::is_convertible<U*, T*>::value && 
                                            std::is_invocable<Deleter, U*>::value>>
    SmartPtr(U* p, Deleter d) : ptr(p) {
        std::cout << "์‚ญ์ œ์ž์™€ ํ•จ๊ป˜ ์ƒ์„ฑ" << std::endl;
        // ์‹ค์ œ๋กœ๋Š” ์—ฌ๊ธฐ์„œ ์‚ญ์ œ์ž๋ฅผ ์ €์žฅํ•˜๊ณ  ์‚ฌ์šฉํ•ด์•ผ ํ•ด์š”
    }

    ~SmartPtr() { delete ptr; }

    T* get() const { return ptr; }
};

struct Base { virtual ~Base() = default; };
struct Derived : Base {};

int main() {
    SmartPtr<Base> ptr1(new Derived);  // OK
    SmartPtr<Base> ptr2(new Base, [](Base* p) { delete p; });  // OK
    // SmartPtr<Derived> ptr3(new Base);  // ์ปดํŒŒ์ผ ์—๋Ÿฌ!

    return 0;
}

์ด ์˜ˆ์ œ์—์„œ SmartPtr ํด๋ž˜์Šค๋Š” SFINAE์™€ ํƒ€์ž… ํŠน์„ฑ์„ ์‚ฌ์šฉํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด์š”:

  • ํฌ์ธํ„ฐ ํƒ€์ž…์ด ๋ณ€ํ™˜ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ์—๋งŒ ์ƒ์„ฑ์ž๋ฅผ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • ์‚ญ์ œ์ž๋ฅผ ๋ฐ›๋Š” ์ƒ์„ฑ์ž๋Š” ํฌ์ธํ„ฐ ํƒ€์ž…์ด ๋ณ€ํ™˜ ๊ฐ€๋Šฅํ•˜๊ณ , ์‚ญ์ œ์ž๊ฐ€ ํ•ด๋‹น ํฌ์ธํ„ฐ ํƒ€์ž…์„ ์ธ์ž๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ์„ ๋•Œ๋งŒ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ SFINAE์™€ ํƒ€์ž… ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด, ์ปดํŒŒ์ผ ํƒ€์ž„์— ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ๋ณด์žฅํ•˜๊ณ  ์ž˜๋ชป๋œ ์‚ฌ์šฉ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๋Š” ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜๋ฅผ ์ค„์ด๊ณ  ์ฝ”๋“œ์˜ ์•ˆ์ •์„ฑ์„ ๋†’์ด๋Š” ๋ฐ ํฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค!

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

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

๐ŸŽ“ ๋งˆ๋ฌด๋ฆฌ: C++ ๋งˆ๋ฒ•์‚ฌ๋กœ ๊ฑฐ๋“ญ๋‚˜๊ธฐ

์™€์šฐ! ์ •๋ง ๊ธด ์—ฌ์ •์ด์—ˆ์ฃ ? ํƒ€์ž… ํŠน์„ฑ๊ณผ SFINAE๋ผ๋Š” C++์˜ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ๋“ค์— ๋Œ€ํ•ด ์•Œ์•„๋ดค์–ด์š”. ์ฒ˜์Œ์—๋Š” ์–ด๋ ค์›Œ ๋ณด์˜€์ง€๋งŒ, ์ด์ œ ์กฐ๊ธˆ์€ ์นœ์ˆ™ํ•ด์ง€์…จ๋‚˜์š”? ใ…Žใ…Ž

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

๐ŸŒŸ ๋ฐฐ์šด ๋‚ด์šฉ ์ •๋ฆฌ

  1. ํƒ€์ž… ํŠน์„ฑ(Type Traits): ์ปดํŒŒ์ผ ํƒ€์ž„์— ํƒ€์ž… ์ •๋ณด๋ฅผ ์–ป๊ณ  ์กฐ์ž‘ํ•˜๋Š” ๋„๊ตฌ
  2. SFINAE: ํ…œํ”Œ๋ฆฟ ์ธ์Šคํ„ด์Šคํ™” ์‹คํŒจ๋ฅผ ์ด์šฉํ•ด ์˜ค๋ฒ„๋กœ๋“œ ํ•ด๊ฒฐ์ด๋‚˜ ํŠน์ˆ˜ํ™”๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ธฐ๋ฒ•
  3. ํƒ€์ž… ํŠน์„ฑ + SFINAE: ์ด ๋‘˜์„ ๊ฒฐํ•ฉํ•ด ๊ฐ•๋ ฅํ•˜๊ณ  ์œ ์—ฐํ•œ ํ…œํ”Œ๋ฆฟ ๋ฉ”ํƒ€ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ตฌํ˜„

์ด ๊ฐœ๋…๋“ค์„ ๋งˆ์Šคํ„ฐํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์€ ์ง„์ •ํ•œ C++ ๋งˆ๋ฒ•์‚ฌ๊ฐ€ ๋  ์ˆ˜ ์žˆ์–ด์š”! ๐Ÿง™โ€โ™‚๏ธโœจ

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

๐Ÿš€ ๋‹ค์Œ ๋‹จ๊ณ„

์—ฌ๊ธฐ์„œ ๋ฐฐ์šด ๋‚ด์šฉ์„ ๋ฐ”ํƒ•์œผ๋กœ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ๋“ค์„ ์‹œ๋„ํ•ด๋ณด๋Š” ๊ฑด ์–ด๋–จ๊นŒ์š”?

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

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

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

์—ฌ๋Ÿฌ๋ถ„์˜ C++ ์—ฌ์ •์— ํ–‰์šด์ด ํ•จ๊ป˜ํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž„๊ฒŒ์š”. ์–ธ์ œ๋“  ์งˆ๋ฌธ์ด ์žˆ๋‹ค๋ฉด, ์žฌ๋Šฅ๋„ท์˜ C++ ์ „๋ฌธ๊ฐ€๋“ค์—๊ฒŒ ๋ฌผ์–ด๋ณด๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ด์—์š”. ํ•จ๊ป˜ ์„ฑ์žฅํ•˜๊ณ  ๋ฐœ์ „ํ•ด ๋‚˜๊ฐ€์š”! ํ™”์ดํŒ…! ๐ŸŽ‰๐Ÿš€