템플릿 및 STL 소개

소개

템플릿은 일반 프로그래밍의 기초입니다.

이전에 함수 오버로딩을 도입했습니다 . 동일한 함수 이름과 다른 매개변수 목록을 사용하여 오버로드된 함수를 여러 개 정의하여 다양한 유형의 유사한 작업을 수행할 수 있습니다. 오버로드된 함수를 호출할 때 전달된 매개 변수에 따라 적절한 오버로드된 함수가 호출되므로 이러한 메서드를 호출하는 데 편리합니다.

그러나 함수 오버로딩에는 여전히 몇 가지 단점이 있습니다.
오버로드된 함수는 여전히 자체적으로 정의해야 하며 코드 재사용률이 높지 않습니다. 구현 유형을 추가해야 할 때 오버로드된 함수를 정의해야 하며 오버로드된 함수의 유지 관리 가능성이 높지 않으며 문제가 발생하면 오버로드된 각 함수를 하나씩 수정해야 할 수 있습니다.

일반 프로그래밍은 이 문제를 해결할 수 있습니다.모든 유형에 공통적인 코드만 작성할 수 있습니다.사용이 필요할 때 컴파일러는 해당 코드를 생성하여 코드 재사용의 수단입니다. 템플릿은 일반 프로그래밍의 기초입니다.

C++ 템플릿은 함수 템플릿과 클래스 템플릿으로 나뉩니다.
여기에 이미지 설명 삽입

기능 템플릿

함수 템플릿은 유형에 관계없이 동일한 작업을 수행하는 함수 클래스를 나타냅니다. 함수 템플릿은 사용될 때 컴파일러에 의해 자동으로 인스턴스화되어 특정 유형의 함수를 생성합니다.

정의

함수
template<typename T1, typename T2, ...typename Tn>
返回值 函数名(参数列表) {}
템플릿을 정의할 수 있습니다. 여기서 typename은 클래스로 대체될 수도 있습니다.

예를 들어 스왑 기능 템플릿은 다음과 같습니다.


template<typename T>
void Swap(T& a, T& b)
{
    
    
	T temp = a;
	a = b;
	b = temp;
}

그런 다음 함수와 마찬가지로 함수 템플릿을 사용할 수 있습니다.

int main()
{
    
    
	int a = 10;
	int b = 20;
	Swap(a, b);
	cout << a << " " << b << endl;
	return 0;
}

여기에 이미지 설명 삽입
템플릿에 의해 선언된 typename은 다음 함수에서만 유효하다는 점에 유의해야 합니다.

인스턴스화

함수 템플릿을 사용할 때 컴파일러는 함수 템플릿의 인스턴스화인 지정된 유형의 함수를 생성합니다.

생성 함수의 유형을 지정할 때 암시적 및 명시적 두 가지 방법이 있습니다.

암시적 인스턴스화

암시적 인스턴스화는 컴파일러가 호출 시 실제 매개변수에 따라 템플릿 매개변수의 유형을 자동으로 지정함을 의미합니다. 예를 들어
다음 코드는 다음과 같습니다.

template<typename T>
T Add(const T& a, const T& b)
{
    
    
	return a + b;
}
int main()
{
    
    
	int a = 10;
	int b = 20;
	cout << Add(a, b) << endl;
	return 0;
}

여기에 이미지 설명 삽입
이때 변수 ab둘 다 int이고 int, 컴파일러는 둘 다 int인 T실제 매개변수 두 개에서 자연스럽게 유형을 유추할 수 있어 int이해하기 어렵지 않다.
그러나 실제 매개변수의 유형이 다른 경우 T두 매개변수 유형 중 어떤 유형인지 판별할 수 없습니다.

	int a = 10;
	double b = 20;
	//cout << Add(a, b) << endl;  //错误代码,调用Add时模板参数不明确

여기에 이미지 설명 삽입
템플릿에서는 승인 없이 유형 변환이 수행되지 않습니다. 예를 들어, 이 경우 유형이 T모호할 때 int를 double로 변환할지 또는 double을 int로 변환할지 확실하지 않습니다.

물론 해결책은 매우 간단합니다.

  1. 매개변수를 전달할 때 실제 매개변수의 유형을 일관성 있게 명시적으로 변환할 수 있습니다.
template<typename T>
T Add(const T& a, const T& b)
{
    
    
	return a + b;
}
int main()
{
    
    
	int a = 10;
	double b = 20;
	cout << Add(a, (int)b) << endl;
	return 0;
}

여기에 이미지 설명 삽입
유형 변환은 임시 변수를 생성하고 임시 변수는 상수라는 점에 유의해야 합니다. 따라서 템플릿의 형식 매개변수 유형을 const수정하지 않으면 권한 증폭이 발생하므로 이 방법은 바람직하지 않습니다.

  1. 물론 명시적으로 type 을 지정하여 T컴파일러가 암시적 유형 변환, 즉 명시적 인스턴스화를 시도하도록 할 수도 있습니다 .

명시적 인스턴스화

명시적 인스턴스화는 호출 시 함수 이름 <>뒤에 템플릿 매개 변수의 유형을 명시적으로 지정하는函数名<模板参数列表>(实参列表);
것입니다. 예를 들어 위의 Add 템플릿 생성 함수 호출:

int main()
{
    
    
	int a = 10;
	double b = 20;
	cout << Add<int>(a, b) << endl; // Add<int>(a, b)
	return 0;
}

여기에 이미지 설명 삽입
템플릿 매개변수의 타입이 지정되면 컴파일러는 매개변수를 전달할 때 암시적 타입 변환을 수행할 수 있으며 변환이 실패하면 오류가 보고됩니다.

알아야 할 사항은 다음과 같습니다.

  1. 비템플릿 함수는 동일한 이름의 함수 템플릿과 동시에 존재할 수 있으며 , 다른 조건이 같을 경우 비템플릿 함수가 먼저 호출되고 호출 시 템플릿에서 인스턴스가 생성되지 않습니다. 더 잘 일치하는 함수를 생성할 수 있는 경우 템플릿이 선택됩니다.

예를 들어:

int Add(const int& a, const int& b)
{
    
    
	return a + b;
}

template<typename T1, typename T2>
T1 Add(const T1& a, const T2& b)
{
    
    
	return a + b;
}
int main()
{
    
    
	cout << Add(1, 2) << endl;
	cout << Add(1, 2.0) << endl;
	return 0;
}

Add 함수가 처음 호출될 때 실제 매개변수 유형은 int이므로 비템플릿 함수가 먼저 호출됩니다.
여기에 이미지 설명 삽입
Add 함수가 두 번째로 호출될 때 첫 번째 매개변수 유형은 int이고 두 번째 매개변수는 템플릿 함수에 의해 생성된 추가가 더 잘 일치할 수 있으므로 템플릿을 호출합니다.
여기에 이미지 설명 삽입
3. 템플릿 함수는 자동 유형 변환을 허용하지 않지만 일반 함수는 자동 유형 변환을 수행할 수 있습니다.

클래스 템플릿

함수와 유사하게 유형 독립적인 클래스, 즉 클래스 템플릿을 정의할 수도 있습니다. 사용될 때 컴파일러에 의해 지정된 템플릿 매개변수 유형에 대한 클래스 유형으로 인스턴스화됩니다.

정의

함수
template<typename T1, typename T2, ...typename Tn>
class 类模板名 {};
템플릿을 정의할 수 있습니다. 여기서 typename은 클래스로 대체될 수도 있습니다.

예를 들어 간단한 스택을 작성할 수 있습니다.

template<typename T>
class Stack
{
    
    
public:
	Stack(size_t size = 0, size_t capacity = 0)  //构造函数
		: _size(size)
		, _capacity(capacity)
		, _date(nullptr)
	{
    
    
		_date = new T[_capacity + 1]{
    
     0 };
	}
	void push(T n)    //压栈
	{
    
    
		if (_size == _capacity)
		{
    
    
			if (_capacity == 0)
			{
    
    
				reserve(6);
			}
			else
			{
    
    
				reserve(_capacity * 2);
			}
		}
		_date[_size] = n;
		++_size;
	}
	void reserve(size_t capacity)    
	{
    
    
		if (capacity > _capacity)
		{
    
    
			T* newdate = new T[capacity + 1]{
    
     0 };
			_capacity = capacity;
			for (int i = 0; i < _size; ++i)
			{
    
    
				newdate[i] = _date[i];
			}
			delete[] _date;
			_date = newdate;
		}
	}
	T top()
	{
    
    
		return _date[_size - 1];
	}
	size_t size()   
	{
    
    
		return _size;
	}
	~Stack()   //析构函数
	{
    
    
		delete[] _date;
		_size = 0;
		_capacity = 0;
	}
private:
	size_t _size;
	size_t _capacity;
	T* _date;
};

int유형 데이터 의 경우 :

int main()
{
    
    
	Stack<int> nums;
	nums.push(1);
	nums.push(2);
	nums.push(3);
	nums.push(4);
	nums.push(5);
	cout << nums.top() << endl;
	cout << nums.size() << endl;
	return 0;
}

여기에 이미지 설명 삽입
char유형 데이터 의 경우 :

int main()
{
    
    
	Stack<char> str;
	str.push('a');
	str.push('b');
	str.push('c');
	str.push('d');
	str.push('e');
	cout << str.top() << endl;
	cout << str.size() << endl;
	return 0;
}

여기에 이미지 설명 삽입
서로 다른 템플릿 매개변수 유형에 대해 이 간단한 스택이 그 효과를 달성할 수 있다는 것을 찾는 것은 어렵지 않습니다.

인스턴스화

함수 템플릿과 달리 클래스 템플릿은 매개변수를 통해 템플릿 매개변수의 유형을 유추할 수 없으므로 클래스 템플릿의 인스턴스화는 <>호출 후 클래스 템플릿 이름에 템플릿 매개변수를 명시적으로 나타내야 합니다.

위의 스택 템플릿 사용 예:

int main()
{
    
    
	//实例化类模板并实例化类对象
	Stack<char> str;
	Stack<int> nums;
	Stack<double> dnums;

	//对不同类型的栈堆栈
	str.push('a');
	str.push('b');
	nums.push(3);
	nums.push(4);
	dnums.push(20.0);
	dnums.push(30.0);

	//打印不同类型栈的栈顶元素及元素个数
	cout << str.top() << endl;
	cout << str.size() << endl;
	cout << nums.top() << endl;
	cout << nums.size() << endl;
	cout << dnums.top() << endl;
	cout << dnums.size() << endl;
	return 0;
}

여기에 이미지 설명 삽입

클래스 템플릿의 이름은 실제 클래스가 아니지만 인스턴스화 결과는 실제 클래스라는 점에 유의해야 합니다.

STL 소개

STL(표준 템플릿 라이브러리-표준 템플릿 라이브러리): 재사용 가능한 구성 요소 라이브러리일 뿐만 아니라 데이터 구조 및 알고리즘을 포함하는 소프트웨어 프레임워크인 C++ 표준 라이브러리의 중요한 부분입니다.

STL 6대 주요 구성 요소

여기에 이미지 설명 삽입
컨테이너: string, vector, list, deque, map, set 등
알고리즘: 찾기, 교체, 역순 정렬 등

(이는 이해를 돕기 위한 것으로 차후에 차차 소개할 예정입니다.)

요약하다


이 시점에서 함수 템플릿 및 클래스 템플릿을 포함한 템플릿의 초기 콘텐츠 소개는 끝났습니다.

제가 특정 부분을 명확하게 소개하지 않았거나 특정 부분에 문제가 있다고 생각하시면 댓글란에 올려주세요.

이 글이 도움이 되셨다면 클릭 한번으로 연결되길 바랍니다

당신과 함께 발전하기를 바랍니다

Supongo que te gusta

Origin blog.csdn.net/weixin_73450183/article/details/131139199
Recomendado
Clasificación