AcceleratedC++/Chapter7 | AcceleratedC++/Chapter9 |
1. Chapter 8 Writing generic functions ¶

Ch9~Ch12

μ°Έκ³ νμ΄μ§) ParametricPolymorphism
1.1. 8.1 What is a generic function? ¶

ν¨μμ νΈμΆμ ν¨μμ λ§€κ°λ³μλ₯Ό operandλ‘ νμ¬ νν΄μ§λ operatorμ μ ν¨μ±μ μ»΄νμΌλ¬κ° μ‘°μ¬. μ¬μ© κ°λ₯μ±μ νλ¨
~cpp ex) union(A, B) { return A+B; } union(A:string, " is...") (O), concaternate("COL", " is...") (X)κ·Έλ λ€λ©΄ μ΄λ»κ² ν¨μκ° μ΄λ ν μλ£κ΅¬μ‘°λ₯Ό λ§μ‘± μν€λμ§ νλ¨ν μ μλκ°?
λ°λ³΅μλ₯Ό μκ°ν΄λ³΄μ. λ§μ½ νΉμ μλ£κ΅¬μ‘°κ° λ°λ³΅μλ₯Ό 리ν΄νλ λ©€λ²ν¨μλ₯Ό κ°λ λ€λ©΄ λ°λ³΅μλ₯Ό μΈμλ‘ λ°λ functionλ€μ λν΄μ κ·Έ μλ£κ΅¬μ‘°λ μ ν¨νλ€κ³ νλ¨ν μ μλ€.
1.1.1. 8.1.1 μλ €μ§μ§ μμ νμ μ μ€μ κ° ¶
template
typename μ μμ§ μΈμ€ν΄μ€ν λμ§ μμ ν¨μλ₯Ό μ»΄νμΌλ¬κ° μ½μ΄λ€μΌλ νμ λ§€κ°λ³μμ κ΄κ³λ νμ μ νμ μμ±ν λ μμ λΆμ¬μΌ νλ ν€μλ μ. ex) vector<T> or vector<T>::size_type
μλ‘ λ€λ₯Έ νμ
μ κ°μ²΄μ΄λΌλ νλλΌλ κ°κ°μ κ°μ²΄λ₯Ό κ°μ§κ³ ννλ νλμμμ 곡ν΅μ νλμμμ κ°λλ€.
Runtimeμ΄ μλλΌ Compile νμμ μ€μ λ‘ νμ μ΄ λ³ννλ κ°μ²΄λ₯Ό μ μ ν μμ±νλ©΄ μ¬λ°λ₯Έ λμμ 보μ₯νλ€.
Runtimeμ΄ μλλΌ Compile νμμ μ€μ λ‘ νμ μ΄ λ³ννλ κ°μ²΄λ₯Ό μ μ ν μμ±νλ©΄ μ¬λ°λ₯Έ λμμ 보μ₯νλ€.
~cpp //median.h #ifndef GUARD_median_h #define GUARD_median_h #include <algorithm> #include <stdexcept> #include <vector> using std::domain_error; using std::sort; using std::vector; template <class T> // type λ§€κ°λ³μμ μ§μ , μ΄ ν¨μμ scopeμμμλ λ°μ΄ν° νμ λμ νλ€. T median(vector<T> v) { typedef typename vector<T>::size_type vec_sz; // typenameμ λν΄μ μμ vec_sz size = v.size(); if (size == 0) throw domain_error("median of an empty vector"); sort(v.begin(), v.end()); vec_sz mid = size/2; return size % 2 == 0 ? (v[mid] + v[mid-1]) / 2 : v[mid]; // double, intμλ μ ν¨, stringμ operator / κ° μκΈ° λλ¬Έμ λ¬΄ν¨ } #endifμ€μ μ»΄νμΌμ μ»΄νμΌλ¬λ νλ‘κ·Έλλ¨Έκ° μ§μ ν νμ μΌλ‘ μ΄ ν¨μλ₯Ό μΈμ€ν΄μ€ν μμΌμ μμ±νκ³ λ°μΈλ©νλ€.
typename μ μμ§ μΈμ€ν΄μ€ν λμ§ μμ ν¨μλ₯Ό μ»΄νμΌλ¬κ° μ½μ΄λ€μΌλ νμ λ§€κ°λ³μμ κ΄κ³λ νμ μ νμ μμ±ν λ μμ λΆμ¬μΌ νλ ν€μλ μ. ex) vector<T> or vector<T>::size_type
1.1.2. 8.1.2 ν νλ¦Ώ μΈμ€ν΄μ€ν ¶
STLμ μ€μ λ‘ ν¨μμ μΈμ€ν΄μ€νμ κ΄ν νμ€μ μΈ λ°©μμ μ μ νμ§ μμλ€. λ°λΌμ κ° μ»΄νμΌλ¬λ§λ€ μλ‘ λ€λ₯Έ λ°©μμΌλ‘ ν¨μλ₯Ό μΈμ€ν΄μ€ννλ€. λ°λΌμ μμ μ μ»΄νμΌλ¬μ νΉμ§μ νμ
νλ λ
Έλ ₯μ΄ νμ.
- μ»΄νμΌ λ§ν¬ λͺ¨λΈ Compiler : μ€μ λ‘ μΈμ€ν΄μ€κ° λ§λ€μ΄μ§κΈ° μ κΉμ§λ ν
νλ¦Ώ μ½λμ μ ν¨μ±μ μ μ μλ€. μλ¬λ λ§ν¬μμ λ°μ
- λ
μμ λ°©μμ template λͺ¨λΈ Compiler : μ΅κ·Όμ λ°©μ. μΈμ€ν΄μ€νλ₯Ό μν΄μ STL μ μλΆμ λν μ κ·Όμ΄ νμ.
1.1.3. 8.1.3 μ λ€λ¦ ν¨μμ νμ ¶
μ€μ μ λ€λ¦ ν¨μμ μ¬μ©μμ κ°μ₯ λ¬Έμ μ λλ κ²μ ν¨μλ΄λΆμ μ°μ°μ λ§€κ°λ³μ νμ
μ΄ μ§μμ νλ κ°μ΄λ€.
max ν¨μμ ꡬν
find(B, E, D) | Dμ μΈμλ£ [B, E)λ₯Ό λΉκ΅νμ¬ κ°μ μ°Ύλλ€. λΉκ΅λ₯Ό νλ κ²μ ν¬κ² λ¬Έμ λμ§ μλλ€. |
accumulate(B, E, D) | Dμ μΈμμ νμ κΈ°μ€μΌλ‘ [B, E)λ₯Ό λΉκ΅νμ¬ κ°μ λͺ¨μλ€. 리ν΄κ°μ΄ Dμ μλ£νμ μν₯μ λ°κΈ° λλ¬Έμ λ¬Έμ μ λ°μμμ§κ° μ‘΄μ¬νλ€. |
~cpp ex) accumulate(v.begin(), v.end(), 0.0); // λ§μ½ 0:intλ₯Ό μ¬μ©νλ€λ©΄ μ¬λ°λ₯Έ λμμ 보μ₯ν μ μλ€.
max ν¨μμ ꡬν
~cpp template <class T> T max(const T& left, const T& right) { return left > right ? left : right; }μΈμλ‘ λ°μ λ κ°μ νμ μ΄ μμ ν κ°μμΌμ§λ§ μ¬λ°λ₯Έ λμμ 보μ₯λ°λλ€. μΈμλ operator>(T, T)λ₯Ό μ§μν΄μΌνλ€.
1.2. 8.2 Data-structure independence ¶
find(c.begin(), c.end(), val) | μΌλ°μ μΈ ν¨μμ μμ± κ°λ₯. λ°λ³΅μλ₯Ό ν΅ν΄μ λ°λ³΅μκ° μ 곡νλ λ°©μμΌλ‘ λμκ°λ₯ |
c.find(val) | νΉμ νμ μΈμ€ν΄μ€μΈ cλ₯Ό ν΅ν΄μλ§ μ κ·Όκ°λ₯. λ΄μ₯λ°°μ΄μ μ μ© λΆκ°λ₯ |
find(c, val) | λ²μ μ§μ μ΄ λΆκ°λ₯νκ³ , μ μ©μ±μ΄ 첫λ²μ§Έμ κ²½μ°λ³΄λ€ μ λ€. |
- 1μ λ°©μμΌλ‘ μμ±λ ν¨μμΌμ΄ rbegin() κ°μ ν
νλ¦Ώ λ©€λ² ν¨μλ₯Ό μ΄μ©ν΄μ μμ κ²μλ κ°λ₯νκ² μμ±λλ€.
1.2.1. 8.2.1 μκ³ λ¦¬μ¦κ³Ό λ°λ³΅μ ¶
STL ν¨μλ₯Ό 보면 μΈμλ‘ λ°λ λ°λ³΅μ(iterator)μ λ°λΌμ 컨ν
μ΄λμ ν¨μ μ¬μ© μ ν¨μ±μ μ μ μλ€.
μλ₯Ό λ€μλ©΄ find(B, E, D)κ°μ ν¨μμ κ²½μ° μμ£Ό λ¨μν μ νμ μ°μ°λ§μ μ΄μ©νκΈ° λλ¬Έμ λλΆλΆμ 컨ν μ΄λμ λν΄μ μ¬μ©μ΄ κ°λ₯νλ€. κ·Έλ¬λ sort(B, E)κ°μ κ²½μ°μλ κΈ°λ³Έμ μΈ μ¬μΉμ°μ°λ€μ λ°λ³΅μμ λν΄μ μ¬μ©νκΈ° λλ¬Έμ μ΄λ° μ°μ°μ μ§μνλ string, vector λ§μ΄ μλ²½νκ² μ§μλλ€.
STLμ μ΄λ° λΆλ₯λ₯Ό μν΄μ 5κ°μ λ°λ³΅μ μΉ΄ν κ³ λ¦¬(iterator category)λ₯Ό μ μνμ¬ λ°λ³΅μλ₯Ό λΆλ₯νλ€. μΉ΄ν κ³ λ¦¬μ λΆλ₯λ λ°λ³΅μμ μμλ₯Ό μ κ·Όνλ λ°©λ²μλ°λ₯Έ λΆλ₯μ΄λ©°, μ΄λ μκ³ λ¦¬μ¦μ μ¬μ© μ ν¨μ± μ¬λΆλ₯Ό κ²°μ νλλ° λμμ΄ λλ€.
μλ₯Ό λ€μλ©΄ find(B, E, D)κ°μ ν¨μμ κ²½μ° μμ£Ό λ¨μν μ νμ μ°μ°λ§μ μ΄μ©νκΈ° λλ¬Έμ λλΆλΆμ 컨ν μ΄λμ λν΄μ μ¬μ©μ΄ κ°λ₯νλ€. κ·Έλ¬λ sort(B, E)κ°μ κ²½μ°μλ κΈ°λ³Έμ μΈ μ¬μΉμ°μ°λ€μ λ°λ³΅μμ λν΄μ μ¬μ©νκΈ° λλ¬Έμ μ΄λ° μ°μ°μ μ§μνλ string, vector λ§μ΄ μλ²½νκ² μ§μλλ€.
STLμ μ΄λ° λΆλ₯λ₯Ό μν΄μ 5κ°μ λ°λ³΅μ μΉ΄ν κ³ λ¦¬(iterator category)λ₯Ό μ μνμ¬ λ°λ³΅μλ₯Ό λΆλ₯νλ€. μΉ΄ν κ³ λ¦¬μ λΆλ₯λ λ°λ³΅μμ μμλ₯Ό μ κ·Όνλ λ°©λ²μλ°λ₯Έ λΆλ₯μ΄λ©°, μ΄λ μκ³ λ¦¬μ¦μ μ¬μ© μ ν¨μ± μ¬λΆλ₯Ό κ²°μ νλλ° λμμ΄ λλ€.
1.2.2. 8.2.2 μμ°¨μ μ½κΈ°-μ μ© μ κ·Ό ¶
β» λͺ¨λ μμ°¨λ°λ³΅μμμλ -- μ°μ°μ ν μ μλ€.
find ꡬν 1
μκΈ°μ κ°μ λ°λ³΅μλ₯Ό μ λ ₯ λ°λ³΅μ(input iterator)λΌκ³ ν¨.
find ꡬν 1
~cpp template <class In, class X> In find(In begin, In end, const X& x) { while(begin != end && *begin != x) ++begin: return begin; }find ꡬν 2
~cpp template <class In, class X> In find(In begin, In end, const X& x) { if (begin == end || *begin == x) return begin; begin++; return find(begin, end, x); }μκΈ° 2κ°μ ꡬν λͺ¨λ begin, end iteratorλ₯Ό μμ°¨μ μΌλ‘ μ κ·Όνκ³ μμμ μ μ μλ€. μκΈ°μ ν¨μλ₯Ό ν΅ν΄μ μμ°¨ μ½κΈ°-μ μ©μ λ°λ³΅μλ ++(μ ,νμ), ==, !=, *λ₯Ό μ§μν΄μΌνλ€λ κ²μ μ μ μλ€. λ§ λΆμ¬μ ->, .μ κ°μ λ©€λ² μ°Έμ‘° μ°μ°μλ νμλ‘νλ€. (7.2μ μ μ¬μ©νλ€ μ°μ°μμ΄λ€.)
μκΈ°μ κ°μ λ°λ³΅μλ₯Ό μ λ ₯ λ°λ³΅μ(input iterator)λΌκ³ ν¨.
1.2.3. 8.2.3 μμ°¨μ μ°κΈ°-μ μ© μ κ·Ό ¶
copy ꡬν
class Out λ°λ³΅μλ₯Ό μΆλ ₯μ λ°°νμ μΌλ‘ μ¬μ©νλ €λ©΄ ++ μ°μ°μ΄ λμ λ¬Έ μ¬μ΄μμ 1λ²μ΄μμ 무ν¨κ° λλλ‘ λ§λ€μ΄ μ£Όμ΄μΌνλ€.
μκΈ° μꡬμ¬νμ λ§μ‘±μν€λ κ²½μ°μ λ°λ³΅μλ₯Ό μΆλ ₯ λ°λ³΅μ(Output iterator)λΌκ³ ν¨.
λͺ¨λ 컨ν μ΄λλ back_inserter(class T)λ₯Ό ν΅ν΄μ μΆλ ₯ λ°λ³΅μλ₯Ό 리ν΄μν¬ μ μλ€. μ΄ λ°λ³΅μλ write-onceμ νΉμ±μ κ°μ§λ€.
~cpp template <class In, class Out> Out copy(In begin, In end, Out dest) { if (begin != end) *dest++ = *begin++; return dest; }class In νμ λ°λ³΅μλ ν¨μκ° μ§νλλ λμ λ°λ³΅μλ₯Ό ν΅ν΄μ μ½κΈ° μ°μ°λ§μ μννλ€. class Out νμ λ°λ³΅μλ *dest++ = *begin++; μ μ°μ°μ ν΅ν΄μ μ°κΈ° μ°μ°μ μννλ€. λ°λΌμ class Out λ°λ³΅μλ ++(μ ,νμ). = μ°μ°μλ§μ νκ°ν μ μμΌλ©΄ λλ€.
class Out λ°λ³΅μλ₯Ό μΆλ ₯μ λ°°νμ μΌλ‘ μ¬μ©νλ €λ©΄ ++ μ°μ°μ΄ λμ λ¬Έ μ¬μ΄μμ 1λ²μ΄μμ 무ν¨κ° λλλ‘ λ§λ€μ΄ μ£Όμ΄μΌνλ€.
μκΈ° μꡬμ¬νμ λ§μ‘±μν€λ κ²½μ°μ λ°λ³΅μλ₯Ό μΆλ ₯ λ°λ³΅μ(Output iterator)λΌκ³ ν¨.
λͺ¨λ 컨ν μ΄λλ back_inserter(class T)λ₯Ό ν΅ν΄μ μΆλ ₯ λ°λ³΅μλ₯Ό 리ν΄μν¬ μ μλ€. μ΄ λ°λ³΅μλ write-onceμ νΉμ±μ κ°μ§λ€.
1.2.4. 8.2.4 μμ°¨μ μ½κΈ°-μ°κΈ° μ κ·Ό ¶
replace ꡬν
μ¬κΈ°μ begλ μ λ ₯ λ°λ³΅μ, μΆλ ₯ λ°λ³΅μ 2κ°μ§μ νΉμ±μ λͺ¨λ λ§μ‘±μμΌμΌ νλ€.
*, ++(μ ,νμ), ==, =, ., ->μ κ°μ μ°μ°μ΄ κ°λ₯νλ€λ©΄ μλ°©ν₯ λ°λ³΅μ(forward iterator)λΌκ³ ν¨.
~cpp template <class For, class X> void replace(For begin, For end, const X& x, const X& y) { while (beg != end) { if (*beg == x) *beg = y; ++beg; } }[begin, end) μ λ²μμμμ xλ₯Ό μ°Ύμμ yλ‘ μΉννλ€.
μ¬κΈ°μ begλ μ λ ₯ λ°λ³΅μ, μΆλ ₯ λ°λ³΅μ 2κ°μ§μ νΉμ±μ λͺ¨λ λ§μ‘±μμΌμΌ νλ€.
*, ++(μ ,νμ), ==, =, ., ->μ κ°μ μ°μ°μ΄ κ°λ₯νλ€λ©΄ μλ°©ν₯ λ°λ³΅μ(forward iterator)λΌκ³ ν¨.
1.2.5. 8.2.5 μλ°©ν₯ μ κ·Ό ¶
reverse ꡬν
μλ°©ν₯ μ°μ°μμ λͺ¨λ μ°μ°μ μ§μνκ³ --μ°μ°μ μ§μνλ€λ©΄ μ΄ λ°λ³΅μλ μλ°©ν₯ λ°λ³΅μ(bidirection iterator) λΌκ³ λΆλ₯Έλ€. νμ€ λΌμ΄λΈλ¬λ¦¬ 컨ν μ΄λ ν΄λμ€λ€μ λͺ¨λ μλ°©ν₯ λ°λ³΅μλ₯Ό μ§μν¨.
~cpp template <class Bi> void reverse(Bi begin, Bi end) { while (begin != end) { --end; if (begin != end) swap(*begin++, *end); } }begin κ³Ό end μ μμλ₯Ό λΉκ΅νμ¬ λ€λ₯΄λ€λ©΄ swap()μν¨λ€.
μλ°©ν₯ μ°μ°μμ λͺ¨λ μ°μ°μ μ§μνκ³ --μ°μ°μ μ§μνλ€λ©΄ μ΄ λ°λ³΅μλ μλ°©ν₯ λ°λ³΅μ(bidirection iterator) λΌκ³ λΆλ₯Έλ€. νμ€ λΌμ΄λΈλ¬λ¦¬ 컨ν μ΄λ ν΄λμ€λ€μ λͺ¨λ μλ°©ν₯ λ°λ³΅μλ₯Ό μ§μν¨.
1.2.6. 8.2.6 μμ μ κ·Ό ¶
binary search ꡬν
Binary_searchλ°μ΄λ리 μμΉ
μμ μ κ·Ό λ°λ³΅μμ κ²½μ° μλ°©ν₯ λ°λ³΅μμ λͺ¨λ νΉμ±κ³Ό ν¨κ» λ€μκ³Ό κ°μ μ°μ°μ λ§μ‘±νλ€.
μμ μ κ·Ό λ°λ³΅μλ₯΄ μ΄μ©νλ μκ³ λ¦¬μ¦μ sort. vector, string λ§μ΄ μμ μ κ·Ό λ°λ³΅μλ₯Ό μ§μνλ€. listλ λΉ λ₯Έ λ°μ΄ν°μ μ½μ , μμ μ μ΅μ ν λμκΈ° λλ¬Έμ μμ°¨μ μΈ μ κ·Όλ§ κ°λ₯ν¨.
~cpp template <class Ran, class X> bool binary_search(Ran begin, Ran end, const X& x) { while (begin < end) { Ran mid = begin + (end - begin ) /2; if (x < *mid) end = mid; else if (*mid < x) begin = mid + 1; else return true; } return false; }μ°Έκ³ μλ£)

μμ μ κ·Ό λ°λ³΅μμ κ²½μ° μλ°©ν₯ λ°λ³΅μμ λͺ¨λ νΉμ±κ³Ό ν¨κ» λ€μκ³Ό κ°μ μ°μ°μ λ§μ‘±νλ€.
condition p:iterator, q:iterator, n:integer |
p+n, p-n, n+p, p+q, pn, p<q, p>q, p<=q, p>q |
μμ μ κ·Ό λ°λ³΅μλ₯΄ μ΄μ©νλ μκ³ λ¦¬μ¦μ sort. vector, string λ§μ΄ μμ μ κ·Ό λ°λ³΅μλ₯Ό μ§μνλ€. listλ λΉ λ₯Έ λ°μ΄ν°μ μ½μ , μμ μ μ΅μ ν λμκΈ° λλ¬Έμ μμ°¨μ μΈ μ κ·Όλ§ κ°λ₯ν¨.
1.2.7. 8.2.7 λ°λ³΅μ λ²μ λ° λ μ§λ κ° ¶
λ°λ³΅μμ λκ°μΌλ‘ 컨ν
μ΄λμ λ§μ§λ§ μμμμ νκ°κ° μ§λ κ°μ μ¬μ©νλ μ΄μ
λ§μ§λ§ μμλ₯Ό λ²μμ λμΌλ‘ μ¬μ©ν¨μΌλ‘μ¨ λ°μνλ νΉλ³ν μ²λ¦¬λ₯Ό μμ λ κ²μ΄ κ°λ₯. (μ€μκ° μ€μ΄λ¬)
λ§μ§λ§ μμλ₯Ό λ²μμ λμΌλ‘ μ ν κ²½μ° λ²μμμ μ°Ύλ κ²μ΄ μμλ μ΄λ₯Ό μλ €μ£Όλ μλ¨μ΄ λΆμ¬νλ€.
λ¨μν != μ°μ°μΌλ‘ λ²μμ μνλ₯Ό λ§μΉλ 쑰건μΌλ‘ μ΄μ©μ΄ κ°λ₯νλ€. <>μ κ°μ ν¬κΈ° μ°μ°μκ° λΆνμνλ€.
λλ²μ§Έ μΈμλ‘ νλκ° μ§λ κ°μ κ°λλ‘ν¨μΌλ‘μ¨ μμ°μ€λ½κ² out-of-rangeμ μν©μ νμ
νλ κ²μ΄ κ°λ₯νλ€.
~cpp c.end() == c.begin() + c.size() // this is true
1.3. 8.3 Input and output iterators ¶
μ
μΆλ ₯ λ°λ³΅μλ 컨ν
μ΄λμ λ°λ³΅μμ΄μΈμ μ‘΄μ¬νλ λ°λ³΅μλ₯Ό νννκΈ° λλ¬Έμ μλ°©ν₯ λ°λ³΅μμ ꡬλ³μν΄.
istream, ostream μ λ°λ³΅μλ₯Ό μ»μμΌλ‘μ¨ μ μΆλ ₯ μ€νΈλ¦Όμ μ μ΄νλ κ²μ΄ κ°λ₯νλ€.
istream, ostream μ λ°λ³΅μλ₯Ό μ»μμΌλ‘μ¨ μ μΆλ ₯ μ€νΈλ¦Όμ μ μ΄νλ κ²μ΄ κ°λ₯νλ€.
~cpp vector<int> v; copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(v)); //istream_iterator<int> λ end-of-file, μλ¬μνλ₯Ό κ°λ¦¬ν¨λ€.C++μ λͺ¨λ μ μΆλ ₯ μ°μ°μ νμ μ§μ μ°μ°μ΄λ€. cin>>s.midterm>>s.final>>s.homework; μμλ νμ μ λ°λΌμ λ€λ₯Έ μΌμ νλ€.
1.4. 8.4 Using iterators for flexibility ¶
~cpp #include <algorithm> #include <cctype> #include <string> using std::find_if; using std::string; using std::isspace; inline bool space(char c) { return isspace(c); } inline bool not_space(char c) { return !isspace(c); } template <class Out> // changed void split(const string& str, Out os) { // changed typedef string::const_iterator iter; iter i = str.begin(); while (i != str.end()) { // ignore leading blanks i = find_if(i, str.end(), not_space); // find end of next word iter j = find_if(i, str.end(), space); // copy the characters in `[i,' `j)' if (i != str.end()) *os++ = string(i, j); // changed i = j; } }
Class Out κ° μλ°©ν₯, μμμ κ·Ό, μΆλ ₯ λ°λ³΅μμ μꡬμ¬νμ λͺ¨λ λ°μ‘±νκΈ° λλ¬Έμ istream_iteratorλ§ μλλΌλ©΄ μ΄λ€ λ°λ³΅μμλ μ°μΌ μ μλ€. μ¦, νΉμ λ³μλ‘μ μ μ₯ λΏλ§μλλΌ console, file λ‘μ ostream μΌλ‘μ μΆλ ₯λ μ§μνλ€. ν λλ¨νκ΅°..
----
AcceleratedC++
----
AcceleratedC++