ν νλ¦Ώ
ν νλ¦Ώ¶
1. ν νλ¦Ώμ΄λ?¶
ν νλ¦Ώμ νμ μ λ 립μ μΈ μΌλ°νλ μ½λλ₯Ό μμ±νλ C++μ κ°λ ₯ν κΈ°λ₯μ λλ€.
βββββββββββββββββββββββββββββββββββββββββββββββ
β ν
νλ¦Ώ (Template) β
βββββββββββββββββββββββββββββββββββββββββββββββ€
β β’ νμ
μ λ§€κ°λ³μλ‘ λ°λ μ½λ β
β β’ μ»΄νμΌ νμμ μ€μ νμ
μΌλ‘ λ체 β
β β’ μ½λ μ¬μ¬μ©μ± κ·Ήλν β
βββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββ¬ββββββββββββββββββ
β ν¨μ ν
νλ¦Ώ β ν΄λμ€ ν
νλ¦Ώ β
β (Function) β (Class) β
βββββββββββββββββββ΄ββββββββββββββββββ
μ ν νλ¦Ώμ΄ νμνκ°?¶
// ν
νλ¦Ώ μμ΄ μ€λ²λ‘λ©μΌλ‘ ꡬν
int max(int a, int b) { return (a > b) ? a : b; }
double max(double a, double b) { return (a > b) ? a : b; }
char max(char a, char b) { return (a > b) ? a : b; }
// ... λͺ¨λ νμ
λ§λ€ λ°λ³΅ νμ
// ν
νλ¦ΏμΌλ‘ ν λ²μ ν΄κ²°
template<typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
2. ν¨μ ν νλ¦Ώ¶
κΈ°λ³Έ λ¬Έλ²¶
#include <iostream>
// ν¨μ ν
νλ¦Ώ μ μ
template<typename T>
T add(T a, T b) {
return a + b;
}
// typename λμ classλ μ¬μ© κ°λ₯ (μλ―Έ λμΌ)
template<class T>
T multiply(T a, T b) {
return a * b;
}
int main() {
// λͺ
μμ νμ
μ§μ
std::cout << add<int>(3, 5) << std::endl; // 8
std::cout << add<double>(3.5, 2.5) << std::endl; // 6
// νμ
μΆλ‘ (μ»΄νμΌλ¬κ° μλμΌλ‘ νμ
κ²°μ )
std::cout << add(10, 20) << std::endl; // 30 (int)
std::cout << add(1.5, 2.5) << std::endl; // 4 (double)
std::cout << multiply(4, 5) << std::endl; // 20
return 0;
}
μ¬λ¬ νμ λ§€κ°λ³μ¶
#include <iostream>
#include <string>
template<typename T, typename U>
void printPair(T first, U second) {
std::cout << first << ", " << second << std::endl;
}
// λ°ν νμ
λ ν
νλ¦ΏμΌλ‘
template<typename T, typename U>
auto addDifferent(T a, U b) -> decltype(a + b) {
return a + b;
}
// C++14: κ°λ¨ν auto λ°ν
template<typename T, typename U>
auto addSimple(T a, U b) {
return a + b;
}
int main() {
printPair(1, "Hello"); // 1, Hello
printPair(3.14, 100); // 3.14, 100
printPair("Name", std::string("Alice")); // Name, Alice
std::cout << addDifferent(10, 3.5) << std::endl; // 13.5 (double)
std::cout << addSimple(5, 2.5) << std::endl; // 7.5
return 0;
}
λΉνμ ν νλ¦Ώ λ§€κ°λ³μ¶
#include <iostream>
#include <array>
// μ μκ°μ ν
νλ¦Ώ λ§€κ°λ³μλ‘
template<typename T, int Size>
class FixedArray {
private:
T data[Size];
public:
T& operator[](int index) { return data[index]; }
const T& operator[](int index) const { return data[index]; }
int size() const { return Size; }
};
// ν¨μμμλ μ¬μ© κ°λ₯
template<int N>
int factorial() {
return N * factorial<N - 1>();
}
template<>
int factorial<0>() {
return 1;
}
int main() {
FixedArray<int, 5> arr;
for (int i = 0; i < arr.size(); i++) {
arr[i] = i * 10;
}
for (int i = 0; i < arr.size(); i++) {
std::cout << arr[i] << " "; // 0 10 20 30 40
}
std::cout << std::endl;
// μ»΄νμΌ νμμ κ³μ°λ¨
std::cout << "5! = " << factorial<5>() << std::endl; // 120
return 0;
}
3. ν΄λμ€ ν νλ¦Ώ¶
κΈ°λ³Έ λ¬Έλ²¶
#include <iostream>
template<typename T>
class Box {
private:
T value;
public:
Box(T v) : value(v) {}
T getValue() const { return value; }
void setValue(T v) { value = v; }
void display() const {
std::cout << "Box: " << value << std::endl;
}
};
int main() {
Box<int> intBox(42);
intBox.display(); // Box: 42
Box<double> doubleBox(3.14);
doubleBox.display(); // Box: 3.14
Box<std::string> stringBox("Hello");
stringBox.display(); // Box: Hello
return 0;
}
λ©€λ² ν¨μ μΈλΆ μ μ¶
#include <iostream>
template<typename T>
class Calculator {
private:
T value;
public:
Calculator(T v);
T add(T x);
T subtract(T x);
void display() const;
};
// λ©€λ² ν¨μ μΈλΆ μ μ μ template μ μΈ νμ
template<typename T>
Calculator<T>::Calculator(T v) : value(v) {}
template<typename T>
T Calculator<T>::add(T x) {
return value + x;
}
template<typename T>
T Calculator<T>::subtract(T x) {
return value - x;
}
template<typename T>
void Calculator<T>::display() const {
std::cout << "Value: " << value << std::endl;
}
int main() {
Calculator<int> calc(10);
std::cout << calc.add(5) << std::endl; // 15
std::cout << calc.subtract(3) << std::endl; // 7
calc.display(); // Value: 10
return 0;
}
μ¬λ¬ νμ λ§€κ°λ³μ¶
#include <iostream>
#include <string>
template<typename K, typename V>
class Pair {
private:
K key;
V value;
public:
Pair(K k, V v) : key(k), value(v) {}
K getKey() const { return key; }
V getValue() const { return value; }
void display() const {
std::cout << key << ": " << value << std::endl;
}
};
int main() {
Pair<std::string, int> age("Alice", 25);
age.display(); // Alice: 25
Pair<int, std::string> student(1001, "Bob");
student.display(); // 1001: Bob
Pair<std::string, double> price("Apple", 1.99);
price.display(); // Apple: 1.99
return 0;
}
κΈ°λ³Έ ν νλ¦Ώ μΈμ¶
#include <iostream>
#include <vector>
template<typename T = int, int Size = 10>
class Array {
private:
T data[Size];
int count = 0;
public:
void add(T value) {
if (count < Size) {
data[count++] = value;
}
}
void display() const {
for (int i = 0; i < count; i++) {
std::cout << data[i] << " ";
}
std::cout << std::endl;
}
int capacity() const { return Size; }
};
int main() {
Array<> arr1; // int, 10 (κΈ°λ³Έκ°)
arr1.add(1);
arr1.add(2);
arr1.display(); // 1 2
Array<double> arr2; // double, 10
arr2.add(1.5);
arr2.add(2.5);
arr2.display(); // 1.5 2.5
Array<std::string, 5> arr3; // string, 5
arr3.add("Hello");
arr3.add("World");
arr3.display(); // Hello World
return 0;
}
4. ν νλ¦Ώ νΉμν¶
μ 체 νΉμν (Full Specialization)¶
#include <iostream>
#include <cstring>
// κΈ°λ³Έ ν
νλ¦Ώ
template<typename T>
class DataHolder {
private:
T data;
public:
DataHolder(T d) : data(d) {}
void display() const {
std::cout << "μΌλ°: " << data << std::endl;
}
};
// char* νμ
μ λν μ 체 νΉμν
template<>
class DataHolder<char*> {
private:
char* data;
public:
DataHolder(const char* d) {
data = new char[strlen(d) + 1];
strcpy(data, d);
}
~DataHolder() { delete[] data; }
void display() const {
std::cout << "char*: " << data << std::endl;
}
};
// bool νμ
μ λν μ 체 νΉμν
template<>
class DataHolder<bool> {
private:
bool data;
public:
DataHolder(bool d) : data(d) {}
void display() const {
std::cout << "bool: " << (data ? "true" : "false") << std::endl;
}
};
int main() {
DataHolder<int> h1(42);
h1.display(); // μΌλ°: 42
DataHolder<char*> h2("Hello");
h2.display(); // char*: Hello
DataHolder<bool> h3(true);
h3.display(); // bool: true
return 0;
}
λΆλΆ νΉμν (Partial Specialization)¶
#include <iostream>
// κΈ°λ³Έ ν
νλ¦Ώ
template<typename T, typename U>
class Pair {
public:
void info() const {
std::cout << "μΌλ° Pair<T, U>" << std::endl;
}
};
// λ νμ
μ΄ κ°μ λ λΆλΆ νΉμν
template<typename T>
class Pair<T, T> {
public:
void info() const {
std::cout << "κ°μ νμ
Pair<T, T>" << std::endl;
}
};
// λ λ²μ§Έκ° intμΌ λ λΆλΆ νΉμν
template<typename T>
class Pair<T, int> {
public:
void info() const {
std::cout << "Pair<T, int>" << std::endl;
}
};
// ν¬μΈν° νμ
λΆλΆ νΉμν
template<typename T, typename U>
class Pair<T*, U*> {
public:
void info() const {
std::cout << "ν¬μΈν° Pair<T*, U*>" << std::endl;
}
};
int main() {
Pair<double, char> p1;
p1.info(); // μΌλ° Pair<T, U>
Pair<double, double> p2;
p2.info(); // κ°μ νμ
Pair<T, T>
Pair<double, int> p3;
p3.info(); // Pair<T, int>
Pair<int*, double*> p4;
p4.info(); // ν¬μΈν° Pair<T*, U*>
return 0;
}
ν¨μ ν νλ¦Ώ νΉμν¶
#include <iostream>
#include <cstring>
// κΈ°λ³Έ ν
νλ¦Ώ
template<typename T>
bool isEqual(T a, T b) {
return a == b;
}
// char* νΉμν
template<>
bool isEqual<const char*>(const char* a, const char* b) {
return strcmp(a, b) == 0;
}
int main() {
std::cout << std::boolalpha;
std::cout << isEqual(10, 10) << std::endl; // true
std::cout << isEqual(3.14, 3.14) << std::endl; // true
std::cout << isEqual("Hello", "Hello") << std::endl; // true (ν¬μΈν° μ£Όμ λΉκ΅)
const char* s1 = "Hello";
const char* s2 = "Hello";
std::cout << isEqual(s1, s2) << std::endl; // true (λ¬Έμμ΄ λ΄μ© λΉκ΅)
return 0;
}
5. κ°λ³ μΈμ ν νλ¦Ώ (Variadic Templates)¶
κΈ°λ³Έ λ¬Έλ²¶
#include <iostream>
// μ¬κ· μ’
λ£ μ‘°κ±΄ (base case)
void print() {
std::cout << std::endl;
}
// κ°λ³ μΈμ ν
νλ¦Ώ
template<typename T, typename... Args>
void print(T first, Args... args) {
std::cout << first;
if (sizeof...(args) > 0) {
std::cout << ", ";
}
print(args...); // μ¬κ· νΈμΆ
}
int main() {
print(1, 2, 3); // 1, 2, 3
print("Hello", 3.14, 42, 'A'); // Hello, 3.14, 42, A
print("Name:", "Alice", "Age:", 25); // Name:, Alice, Age:, 25
return 0;
}
ν©κ³ κ³μ°¶
#include <iostream>
// μ¬κ· μ’
λ£
template<typename T>
T sum(T value) {
return value;
}
// κ°λ³ μΈμ
template<typename T, typename... Args>
T sum(T first, Args... args) {
return first + sum(args...);
}
int main() {
std::cout << sum(1, 2, 3, 4, 5) << std::endl; // 15
std::cout << sum(1.5, 2.5, 3.0) << std::endl; // 7
std::cout << sum(10) << std::endl; // 10
return 0;
}
sizeof... μ°μ°μ¶
#include <iostream>
template<typename... Args>
void countArgs(Args... args) {
std::cout << "μΈμ κ°μ: " << sizeof...(Args) << std::endl;
std::cout << "μΈμ κ°μ: " << sizeof...(args) << std::endl; // κ°μ κ²°κ³Ό
}
int main() {
countArgs(); // μΈμ κ°μ: 0
countArgs(1); // μΈμ κ°μ: 1
countArgs(1, 2, 3); // μΈμ κ°μ: 3
countArgs("a", 1, 3.14, 'c'); // μΈμ κ°μ: 4
return 0;
}
ν΄λ ννμ (C++17)¶
#include <iostream>
// C++17 ν΄λ ννμμΌλ‘ κ°λ¨νκ²
template<typename... Args>
auto sumFold(Args... args) {
return (args + ...); // μ°μΈ‘ ν΄λ
}
template<typename... Args>
void printFold(Args... args) {
((std::cout << args << " "), ...); // μ½€λ§ μ°μ°μ ν΄λ
std::cout << std::endl;
}
template<typename... Args>
bool allTrue(Args... args) {
return (args && ...); // λͺ¨λ trueμΈμ§
}
template<typename... Args>
bool anyTrue(Args... args) {
return (args || ...); // νλλΌλ trueμΈμ§
}
int main() {
std::cout << sumFold(1, 2, 3, 4, 5) << std::endl; // 15
printFold(1, "Hello", 3.14); // 1 Hello 3.14
std::cout << std::boolalpha;
std::cout << allTrue(true, true, true) << std::endl; // true
std::cout << allTrue(true, false, true) << std::endl; // false
std::cout << anyTrue(false, false, true) << std::endl; // true
return 0;
}
6. SFINAE¶
SFINAE (Substitution Failure Is Not An Error): ν νλ¦Ώ μΈμ λ체 μ€ν¨λ μλ¬κ° μλλλ€.
κΈ°λ³Έ κ°λ ¶
#include <iostream>
#include <type_traits>
// μ μ νμ
μΌ λλ§ νμ±ν
template<typename T>
typename std::enable_if<std::is_integral<T>::value, void>::type
process(T value) {
std::cout << "μ μ: " << value << std::endl;
}
// λΆλμμμ νμ
μΌ λλ§ νμ±ν
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value, void>::type
process(T value) {
std::cout << "μ€μ: " << value << std::endl;
}
int main() {
process(42); // μ μ: 42
process(3.14); // μ€μ: 3.14
// process("Hi"); // μ»΄νμΌ μλ¬ (λ λ€ λ§€μΉ μ λ¨)
return 0;
}
C++17 if constexpr¶
#include <iostream>
#include <type_traits>
template<typename T>
void process(T value) {
if constexpr (std::is_integral_v<T>) {
std::cout << "μ μ: " << value * 2 << std::endl;
} else if constexpr (std::is_floating_point_v<T>) {
std::cout << "μ€μ: " << value / 2 << std::endl;
} else {
std::cout << "κΈ°ν: " << value << std::endl;
}
}
int main() {
process(10); // μ μ: 20
process(5.0); // μ€μ: 2.5
process("Hello"); // κΈ°ν: Hello
return 0;
}
7. νμ νΉμ± (Type Traits)¶
κΈ°λ³Έ νμ νΉμ±¶
#include <iostream>
#include <type_traits>
int main() {
std::cout << std::boolalpha;
// νμ
κ²μ¬
std::cout << "is_integral<int>: "
<< std::is_integral<int>::value << std::endl; // true
std::cout << "is_integral<double>: "
<< std::is_integral<double>::value << std::endl; // false
std::cout << "is_floating_point<double>: "
<< std::is_floating_point<double>::value << std::endl; // true
std::cout << "is_pointer<int*>: "
<< std::is_pointer<int*>::value << std::endl; // true
std::cout << "is_class<std::string>: "
<< std::is_class<std::string>::value << std::endl; // true
// νμ
λ³ν
std::cout << "is_same<int, int>: "
<< std::is_same<int, int>::value << std::endl; // true
using NoRef = std::remove_reference<int&>::type;
std::cout << "is_same<NoRef, int>: "
<< std::is_same<NoRef, int>::value << std::endl; // true
return 0;
}
μ‘°κ±΄λΆ νμ μ ν¶
#include <iostream>
#include <type_traits>
template<bool Condition, typename T, typename F>
struct MyConditional {
using type = T;
};
template<typename T, typename F>
struct MyConditional<false, T, F> {
using type = F;
};
int main() {
// std::conditional μ¬μ©
using Type1 = std::conditional<true, int, double>::type;
using Type2 = std::conditional<false, int, double>::type;
std::cout << std::boolalpha;
std::cout << "Type1 is int: "
<< std::is_same<Type1, int>::value << std::endl; // true
std::cout << "Type2 is double: "
<< std::is_same<Type2, double>::value << std::endl; // true
// ν¬κΈ°μ λ°λ₯Έ νμ
μ ν
using SmallType = std::conditional<(sizeof(int) > 4), long, int>::type;
std::cout << "SmallType size: " << sizeof(SmallType) << std::endl;
return 0;
}
8. Concepts (C++20)¶
κΈ°λ³Έ λ¬Έλ²¶
#include <iostream>
#include <concepts>
// concept μ μ
template<typename T>
concept Numeric = std::is_arithmetic_v<T>;
template<typename T>
concept Addable = requires(T a, T b) {
{ a + b } -> std::same_as<T>;
};
// concept μ¬μ©
template<Numeric T>
T square(T x) {
return x * x;
}
// requires μ μ¬μ©
template<typename T>
requires Addable<T>
T add(T a, T b) {
return a + b;
}
// μΆμ½ν
auto multiply(Numeric auto a, Numeric auto b) {
return a * b;
}
int main() {
std::cout << square(5) << std::endl; // 25
std::cout << square(3.5) << std::endl; // 12.25
// square("Hi"); // μλ¬: Numeric μ μ½ λΆλ§μ‘±
std::cout << add(10, 20) << std::endl; // 30
std::cout << multiply(3, 4) << std::endl; // 12
return 0;
}
νμ€ Concepts¶
#include <iostream>
#include <concepts>
#include <string>
// νμ€ concept μ¬μ©
template<std::integral T>
void processInt(T value) {
std::cout << "μ μ: " << value << std::endl;
}
template<std::floating_point T>
void processFloat(T value) {
std::cout << "μ€μ: " << value << std::endl;
}
template<std::convertible_to<std::string> T>
void processString(T value) {
std::string s = value;
std::cout << "λ¬Έμμ΄: " << s << std::endl;
}
int main() {
processInt(42);
processFloat(3.14);
processString("Hello");
return 0;
}
9. μ€μ©μ μΈ ν νλ¦Ώ μμ ¶
μ λ€λ¦ μ€ν¶
#include <iostream>
#include <vector>
#include <stdexcept>
template<typename T>
class Stack {
private:
std::vector<T> data;
public:
void push(const T& value) {
data.push_back(value);
}
T pop() {
if (empty()) {
throw std::runtime_error("μ€νμ΄ λΉμ΄μμ΅λλ€");
}
T value = data.back();
data.pop_back();
return value;
}
T& top() {
if (empty()) {
throw std::runtime_error("μ€νμ΄ λΉμ΄μμ΅λλ€");
}
return data.back();
}
bool empty() const { return data.empty(); }
size_t size() const { return data.size(); }
};
int main() {
Stack<int> intStack;
intStack.push(1);
intStack.push(2);
intStack.push(3);
while (!intStack.empty()) {
std::cout << intStack.pop() << " "; // 3 2 1
}
std::cout << std::endl;
Stack<std::string> strStack;
strStack.push("Hello");
strStack.push("World");
std::cout << strStack.top() << std::endl; // World
return 0;
}
ν©ν 리 ν¨μ¶
#include <iostream>
#include <memory>
#include <string>
// make ν¨μ ν
νλ¦Ώ
template<typename T, typename... Args>
std::unique_ptr<T> make(Args&&... args) {
return std::make_unique<T>(std::forward<Args>(args)...);
}
class Person {
public:
std::string name;
int age;
Person(std::string n, int a) : name(n), age(a) {
std::cout << "Person μμ±: " << name << std::endl;
}
void introduce() const {
std::cout << name << ", " << age << "μΈ" << std::endl;
}
};
int main() {
auto p = make<Person>("Alice", 25);
p->introduce(); // Alice, 25μΈ
auto nums = make<std::vector<int>>(std::initializer_list<int>{1, 2, 3});
for (int n : *nums) {
std::cout << n << " "; // 1 2 3
}
std::cout << std::endl;
return 0;
}
νμ μμ printf¶
#include <iostream>
#include <sstream>
#include <string>
// μ¬κ· μ’
λ£
void safePrint(std::ostream& os, const char* format) {
while (*format) {
if (*format == '%' && *(format + 1) != '%') {
throw std::runtime_error("μΈμ λΆμ‘±");
}
if (*format == '%' && *(format + 1) == '%') {
format++; // %% 건λλ°κΈ°
}
os << *format++;
}
}
// κ°λ³ μΈμ μ²λ¦¬
template<typename T, typename... Args>
void safePrint(std::ostream& os, const char* format, T value, Args... args) {
while (*format) {
if (*format == '%') {
if (*(format + 1) == '%') {
os << '%';
format += 2;
continue;
}
os << value;
safePrint(os, format + 1, args...);
return;
}
os << *format++;
}
throw std::runtime_error("μΈμκ° λ무 λ§μ");
}
template<typename... Args>
std::string format(const char* fmt, Args... args) {
std::ostringstream oss;
safePrint(oss, fmt, args...);
return oss.str();
}
int main() {
std::cout << format("μ΄λ¦: %, λμ΄: %μΈ", "Alice", 25) << std::endl;
// μ΄λ¦: Alice, λμ΄: 25μΈ
std::cout << format("% + % = %", 10, 20, 30) << std::endl;
// 10 + 20 = 30
return 0;
}
10. ν νλ¦Ώ μ»΄νμΌ λͺ¨λΈ¶
ν€λμ μ μν΄μΌ νλ μ΄μ ¶
μΌλ° ν¨μ: ν
νλ¦Ώ:
βββββββββββββββ βββββββββββββββ
β header.h β β header.h β
β μ μΈλ§ β β μ μΈ + μ μ β
βββββββββββββββ βββββββββββββββ
β β
βΌ βΌ
βββββββββββββββ βββββββββββββββ
β source.cpp β β (μ¬μ©μ²μμ β
β μ μ β β μΈμ€ν΄μ€ν) β
βββββββββββββββ βββββββββββββββ
μ¬λ°λ₯Έ ν νλ¦Ώ ꡬ쑰¶
// mytemplate.h
#ifndef MYTEMPLATE_H
#define MYTEMPLATE_H
template<typename T>
class MyContainer {
private:
T* data;
size_t size;
public:
MyContainer(size_t n);
~MyContainer();
T& operator[](size_t index);
size_t getSize() const;
};
// ν
νλ¦Ώ μ μλ ν€λμ ν¬ν¨
template<typename T>
MyContainer<T>::MyContainer(size_t n)
: data(new T[n]), size(n) {}
template<typename T>
MyContainer<T>::~MyContainer() {
delete[] data;
}
template<typename T>
T& MyContainer<T>::operator[](size_t index) {
return data[index];
}
template<typename T>
size_t MyContainer<T>::getSize() const {
return size;
}
#endif
λͺ μμ μΈμ€ν΄μ€ν (μ νμ )¶
// mytemplate.cpp
#include "mytemplate.h"
// νΉμ νμ
μ λν΄ λͺ
μμ μΈμ€ν΄μ€ν
template class MyContainer<int>;
template class MyContainer<double>;
template class MyContainer<std::string>;
11. μμ½¶
| κ°λ | μ€λͺ |
|---|---|
| ν¨μ ν νλ¦Ώ | νμ μ λ 립μ μΈ ν¨μ |
| ν΄λμ€ ν νλ¦Ώ | νμ μ λ 립μ μΈ ν΄λμ€ |
| ν νλ¦Ώ νΉμν | νΉμ νμ μ λν νΉλ³ ꡬν |
| λΆλΆ νΉμν | μΌλΆ 쑰건μ λν νΉμν |
| κ°λ³ μΈμ ν νλ¦Ώ | μμ κ°μμ μΈμ μ²λ¦¬ |
| SFINAE | λ체 μ€ν¨λ μλ¬ μλ |
| Concepts (C++20) | ν νλ¦Ώ μ μ½ μ‘°κ±΄ |
| λΉνμ λ§€κ°λ³μ | κ°μ ν νλ¦Ώ μΈμλ‘ |
12. μ°μ΅ λ¬Έμ ¶
μ°μ΅ 1: μ΅μ/μ΅λκ° ν¨μ¶
μμ κ°μμ μΈμμμ μ΅μκ°κ³Ό μ΅λκ°μ λ°ννλ ν¨μ ν νλ¦Ώμ μμ±νμΈμ.
μ°μ΅ 2: μ λ€λ¦ Queue¶
Stack μμ λ₯Ό μ°Έκ³ νμ¬ Queue ν΄λμ€ ν νλ¦Ώμ μμ±νμΈμ.
μ°μ΅ 3: νμ λ³ μ§λ ¬ν¶
λ€μν νμ
μ λ¬Έμμ΄λ‘ λ³ννλ serialize ν¨μ ν
νλ¦Ώμ μμ±νμΈμ. (κΈ°λ³Έ νμ
, 컨ν
μ΄λ λ±)
λ€μ λ¨κ³¶
13_Exceptions_and_File_IO.mdμμ μμΈ μ²λ¦¬μ νμΌ I/Oλ₯Ό λ°°μλ΄ μλ€!