C Programming Language/C++

C++ Generic Programming : ν…œν”Œλ¦Ώ(Templates)

567Rabbit 2024. 8. 31. 21:34

Templates(ν…œν”Œλ¦Ώ)

- 컴파일러λ₯Ό μœ„ν•œ νŒ¨ν„΄μ˜ μ’…λ₯˜

- μ„œλ‘œ λ‹€λ₯Έ νƒ€μž…μ΄λ‚˜ κ°’μœΌλ‘œ ν…œν”Œλ¦Ώμ„ μΈμŠ€ν„΄μŠ€ν™” ν•  수 있음

- ν…œν”Œλ¦Ώμ€ ν”„λ‘œκ·Έλž˜λ¨Έμ˜ μž‘μ—…μ„ 쀄여주며, μ•½κ°„ λ‹€λ₯Έ νƒ€μž… λ•Œλ¬Έμ— μ—¬λŸ¬ 번 ν•¨μˆ˜λ₯Ό κ΅¬ν˜„ν•˜μ§€ μ•Šμ•„λ„ 됨

- ν…œν”Œλ¦Ώμ€ 항상 ν‚€μ›Œλ“œ template 으둜 μ‹œμž‘λ¨

 

예제)

 

cout << min(i1, i2) << endl; μ—μ„œ μ»΄νŒŒμΌλŸ¬λŠ” int둜 minν•¨μˆ˜λ₯Ό μƒμ„±ν•˜κ³ ,

cout << min<float> (f1, f2) << endl;  μ—μ„œ μ»΄νŒŒμΌλŸ¬λŠ” float둜 minν•¨μˆ˜λ₯Ό μƒμ„±ν•œλ‹€

 

이처럼 μ—¬λŸ¬ 번 ν•¨μˆ˜λ₯Ό κ΅¬ν˜„ν•˜μ§€ μ•Šκ³ λ„ λ‹€λ₯Έ νƒ€μž…μ„ μΈμ‹ν•˜κ²Œ ν•΄μ£ΌλŠ” 것이 ν…œν”Œλ¦Ώμ˜ μž₯점이닀.

 

 

 

μΈμŠ€ν„΄μŠ€ν™”λž€?

 

- ν…œν”Œλ¦Ώμ„ μ‚¬μš©ν•˜λ©΄ μΈμŠ€ν„΄μŠ€(객체)ν™” λ˜λŠ”λ°, μ΄λŠ” μ»΄νŒŒμΌλŸ¬κ°€ ν…œν”Œλ¦Ώμ„ ꡬ체적인 인자둜 λŒ€μ²΄ν•˜κΈ° λ•Œλ¬Έ

- μ»΄νŒŒμΌλŸ¬λŠ” ν•¨μˆ˜λ‘œ λ„˜κ²¨μ§„ μΈμžκ°’μ„ μ΄μš©ν•΄ ν…œν”Œλ¦Ώμ„ μžλ™μœΌλ‘œ μΈμŠ€ν„΄μŠ€ν™” ν•œλ‹€

- μ»΄νŒŒμΌλŸ¬κ°€ 인자λ₯Ό κ²°μ •ν•˜μ§€ λͺ»ν•˜λ©΄ λͺ…μ‹œμ μœΌλ‘œ κΈ°μˆ ν•΄μ•Ό ν•œλ‹€

 

 

 

 

Specializations

 

ν…œν”Œλ¦Ώ 객체의 νŠΉμ •ν•œ κ²½μš°μ— μœ μ—°μ„±μ΄λ‚˜ μ‹€ν–‰ νŠœλ‹μ˜ μ€‘μš”ν•œ νˆ΄λ‘œμ„œ μž‘μš©ν•˜κΈ° μœ„ν•΄

λ‹€μŒκ³Ό 같이 ν…œν”Œλ¦Ώμ„ Specializationsν•˜κ²Œ μ‚¬μš©ν•  μˆ˜λ„ μžˆλ‹€.

cpp
λ‹«κΈ°
template <> bool equal (const double& a, const double& b) { ​​​​return std::abs(a-b) < 0.00001; }

 

 

μ‚¬μš©ν•  λ•ŒλŠ”, λ‹€μŒκ³Ό 같이 general version을 λ¨Όμ € μ •μ˜ν•˜κ³  특수 경우의 ν…œν”Œλ¦Ώμ„ μ •μ˜ν•΄μ•Ό ν•œλ‹€

cpp
λ‹«κΈ°
// general version을 λ¨Όμ € μ •μ˜ν•œλ‹€ template <class T> void sort(List<T>& v) { ... } // specializationsλ₯Ό λ‹€μŒμ— μ •μ˜ν•œλ‹€ template <> void sort(List<char *>& v) { ... }

 

 

 

 

 

Templates(ν…œν”Œλ¦Ώ)의 Parameter(νŒŒλΌλ―Έν„°)

 

 

 

 

 

 

<ν…œν”Œλ¦Ώμ˜ μ’…λ₯˜>

 

1. ν•¨μˆ˜ ν…œν”Œλ¦Ώ(Function Template)

2. 클래슀 ν…œν”Œλ¦Ώ(Class Template)  : μ»¨ν…Œμ΄λ„ˆ 클래슀(List, Array, Set, Queue, Stack ...)μ—μ„œ 많이 μ‚¬μš©

3. κ°€λ³€ 길이 ν…œν”Œλ¦Ώ(Variadic  Template) : parameter pack

4. λ³€μˆ˜ ν…œν”Œλ¦Ώ

 

 

 

ν•¨μˆ˜ ν…œν”Œλ¦Ώ (Function Template)

- μ„œλ‘œ λ‹€λ₯Έ νƒ€μž…μ— λŒ€ν•΄ ν†΅μΌλœ κΈ°λŠ₯을 κ΅¬ν˜„ν•  수 있음

- ν…œν”Œλ¦Ώ νŒŒλΌλ―Έν„°λŠ” νƒ€μž…(types)μ΄λ‚˜ κ°’(values)

- νƒ€μž…μ€ typenameμ΄λ‚˜ class둜 μ‹œμž‘ν•¨

- ν…œν”Œλ¦Ώ νŒŒλΌλ―Έν„°μ˜ 이름은 typename 뒀에 옴

- 이름은 첫 번째 νŒŒλΌλ―Έν„°λŠ” 보톡 T둜 두 번째 νŒŒλΌλ―Έν„°λŠ” Uλ₯Ό 씀  ex) template <typename T=int, typename U=double>

- ν•¨μˆ˜ μ•ˆμ—μ„œ 이 이름을 νŠΉμ • νƒ€μž… λŒ€μ‹ μ— μ‚¬μš©ν•¨

 

cpp
λ‹«κΈ°
#include <iostream> template <typename T> T min(const T& a, const T& b) { ​​​​return (a < b) ? a : b } int main(){ ​​​​const int a = 2; ​​​​const int b = 1; ​​​​std::cout << min(a, b) << std::endl; }

 

cpp
λ‹«κΈ°
#include <vector> using namespace std; template <typename T> const T* find(const vector<t>& data, const T& v) { ​​​​for (auto i = 0; i < data.size(); i++) β€Œβ€‹β€‹β€‹β€‹if(data[i] == y) β€Œβ€‹β€‹β€‹β€‹β€‹β€‹β€‹β€‹return &data[i]; ​​​​return nullptr; } int main() { ​​​​vector <int> v; ​​​​//insert some elements ​​​​const int *found = find(v, 7); ​​​​if (found != nullptr) ​​​​... }

 

 

 

클래슀 ν…œν”Œλ¦Ώ (Class Template)

- ν•¨μˆ˜ ν…œν”Œλ¦Ώκ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ ν‚€μ›Œλ“œ template으둜 μ‹œμž‘ν•¨

- ν•¨μˆ˜ ν…œν”Œλ¦Ώμ˜ λŒ€λΆ€λΆ„ κ·œμΉ™μ΄ 클래슀 ν…œν”Œλ¦Ώμ—λ„ 적용됨

- 멀버 ν•¨μˆ˜λŠ” 클래슀의 λ‚΄λΆ€λ‚˜ λ°–μ—μ„œ κ΅¬ν˜„ κ°€λŠ₯함

- 클래슀 λ°–μ—μ„œ κ΅¬ν˜„ν•  λ•ŒλŠ” template-headκ°€ ν•„μš”ν•¨

 

C++ 17λΆ€ν„° 클래슀 ν…œν”Œλ¦Ώμ€ 인자λ₯Ό μžλ™μœΌλ‘œ μΆ”λ‘ ν•  수 μ—†μŒ *** (μžλ™ μΈμŠ€ν„΄μŠ€ν™”κ°€ λΆˆκ°€λŠ₯ν•˜λ‹€)

κ·ΈλŸ¬λ―€λ‘œ κ°œλ³„ ν…œν”Œλ¦Ώ μΈμžλ“€μ€ λͺ…μ‹œμ μœΌλ‘œ κΈ°μˆ λ˜μ–΄μ•Ό ν•œλ‹€

cpp
λ‹«κΈ°
#include <iostream> #include <vector> using namespace std; int main(){ ​​​​vector vec = {1, 2, 3}; ​​​​for (const auto& i : vec) β€Œβ€‹β€‹β€‹β€‹cout << i << " "; }

 

 

 

Method Templates

 

클래슀 ν…œν”Œλ¦Ώμ˜ λ©”μ„œλ“œλŠ” μžμ‹ λ§Œμ˜ ν…œν”Œλ¦Ώμ„ κ°€μ§ˆ 수 있음

- λ©”μ„œλ“œ ν…œν”Œλ¦Ώμ€ 클래슀의 λ‚΄λΆ€λ‚˜ 밖에 μ •μ˜λ  수 있음

- 볡사 μƒμ„±μžμ™€ μ†Œλ©ΈμžλŠ” ν…œν”Œλ¦Ώμ΄ 될 수 μ—†μŒ

cpp
λ‹«κΈ°
#include <iostream> template <typename T> // T 첫 번째 νŒŒλΌλ―Έν„° class Foo { public: ​​​​Foo(const T& x) : mX{x} {} ​​​​ ​​​​template<typename U> // U 두 번째 νŒŒλΌλ―Έν„° ​​​​Foo<T>& operator=(const U& u){ β€Œβ€‹β€‹β€‹β€‹mX = static_cast<T>(u); ​​​​​​​​return *this; ​​​​} private: ​​​​T mX; };

 

 

 

 

κ°€λ³€ 길이 ν…œν”Œλ¦Ώ(Variadic  Template)

1. typenema... Ts : optional name을 κ°€μ§„ ν…œν”Œλ¦Ώ νŒŒλΌλ―Έν„° 팩. νƒ€μž…μ„ 생성

2. Args... ts : optional name을 κ°€μ§„ ν•¨μˆ˜ 인자 νŒŒλΌλ―Έν„° 팩

3. sizeof...(ts) : 전달받은 인자의 개수λ₯Ό κ²°μ •

4. ts... : ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μΈμžλ“€μ„ μ–ΈνŒ©(unpack)함. tsλ₯Ό 인수둜 λ°›μ•„μ„œ 콀마(,)둜 ꡬ뢄