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ํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

template <>
bool equal (const double& a, const double& b) {
    return std::abs(a-b) < 0.00001;
}

 

 

์‚ฌ์šฉํ•  ๋•Œ๋Š”, ๋‹ค์Œ๊ณผ ๊ฐ™์ด general version์„ ๋จผ์ € ์ •์˜ํ•˜๊ณ  ํŠน์ˆ˜ ๊ฒฝ์šฐ์˜ ํ…œํ”Œ๋ฆฟ์„ ์ •์˜ํ•ด์•ผ ํ•œ๋‹ค

// 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>

- ํ•จ์ˆ˜ ์•ˆ์—์„œ ์ด ์ด๋ฆ„์„ ํŠน์ • ํƒ€์ž… ๋Œ€์‹ ์— ์‚ฌ์šฉํ•จ

 

#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;
}

 

#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๋ถ€ํ„ฐ ํด๋ž˜์Šค ํ…œํ”Œ๋ฆฟ์€ ์ธ์ž๋ฅผ ์ž๋™์œผ๋กœ ์ถ”๋ก ํ•  ์ˆ˜ ์—†์Œ *** (์ž๋™ ์ธ์Šคํ„ด์Šคํ™”๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค)

๊ทธ๋Ÿฌ๋ฏ€๋กœ ๊ฐœ๋ณ„ ํ…œํ”Œ๋ฆฟ ์ธ์ž๋“ค์€ ๋ช…์‹œ์ ์œผ๋กœ ๊ธฐ์ˆ ๋˜์–ด์•ผ ํ•œ๋‹ค

#include <iostream>
#include <vector>

using namespace std;
int main(){
    vector vec = {1, 2, 3};
    for (const auto& i : vec)
    	cout << i << " ";
}

 

 

 

Method Templates

 

ํด๋ž˜์Šค ํ…œํ”Œ๋ฆฟ์˜ ๋ฉ”์„œ๋“œ๋Š” ์ž์‹ ๋งŒ์˜ ํ…œํ”Œ๋ฆฟ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Œ

- ๋ฉ”์„œ๋“œ ํ…œํ”Œ๋ฆฟ์€ ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€๋‚˜ ๋ฐ–์— ์ •์˜๋  ์ˆ˜ ์žˆ์Œ

- ๋ณต์‚ฌ ์ƒ์„ฑ์ž์™€ ์†Œ๋ฉธ์ž๋Š” ํ…œํ”Œ๋ฆฟ์ด ๋  ์ˆ˜ ์—†์Œ

#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๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›์•„์„œ ์ฝค๋งˆ(,)๋กœ ๊ตฌ๋ถ„