[cpp] template

minjubyeon·2025년 5월 21일

cpp

목록 보기
14/26

1.template

template <typename T>
bool equal(T a, T b) {
	return a == b;
}

→ T 타입의 변수 a와 b를 선언하고 a == b를 반환하는 equal 함수를 템플릿으로 정의하였다.



🔚 결론

용어의미예시
클래스설계도class Car { ... }
인스턴스설계도로 만든 실체Car myCar;
함수 템플릿함수 설계도template <typename T> bool equal(...)
인스턴스화된 함수타입이 채워진 실제 함수equal<int>(...)


2. Explicit Template Instantiation

template bool equal<int>(int, int);
template bool equal<>(double, double);
template bool equal(char, char);

→ int 타입의 변수 두 개를 받아 비교하는 equal 함수 템플릿을 명시적으로 인스턴스화하였다.
→ double 타입의 변수 두 개를 받아 비교하는 equal 함수 템플릿을 명시적으로 인스턴스화하였다.
→ char 타입의 변수 두 개를 받아 비교하는 equal 함수 템플릿을 명시적으로 인스턴스화하였다.


컴파일러에게

  • int type에 대한 equal
  • double type에 대한 equal
  • char type에 대한 equal

함수를 미리 만들어 두라는 지시

보통 헤더와 소스가 분리된 경우 필요하다. 이 예제에서는 없어도 컴파일은 잘 된다.


🔍 instance란?

클래스를 기반으로 만들어진 '실제 객체'

클래스(class) = 설계도
인스턴스(instance) = 그 설계도로 만든 실제 물건

template <typename T>
bool equal(T a, T b) { 
	return a == b;
    }

→ equal 함수의 설계도

equal(1, 2);  // T = int

→ 컴파일러가 T=int인 equal 함수의 실제 구현을 만들어냄
→ equal int 함수의 instanvce



2-1. typename

template <typename T>
bool equal(T a, T b) {
    return a == b;
}

typename T
→ T는 int, double, char 등 어떤 자료형이든 될 수 있다.


⚠️ 차이점 (typename vs class)

template <typename T> // OK
template <class T>    // OK

typename과 class는 둘 다 "타입 매개변수"를 선언하는 키워드이고, 기능은 완전히 동일하다.

그러나 요즘은 typename을 선호하는 경향이 많다. class는 클래스 선언에도 쓰이기 때문에 헷갈릴 수 있기 때문이다.


🔍 <> 이 괄호의 역할?

<>의 유무는 컴파일러가 타입을 추론하는지, 명시하는지에 따라 차이가 있다.


형태의미
equal<int>(int, int);int 타입으로 명시적으로 템플릿 인스턴스를 생성합니다.
equal<>(double, double);타입을 컴파일러가 추론하게 합니다. 이 경우, 인자만 보고 Tdouble임을 자동 판단합니다.
equal(char, char);이건 사실 템플릿 인스턴스화가 아니라 일반 함수 선언처럼 보이지만, 컴파일러는 이것도 템플릿으로 해석합니다. 단, equal<char>을 암시적으로 인스턴스화합니다.


🔍 <> 괄호 안 써도 되는가?

대부분의 경우, 컴파일러가 타입을 자동 추론해주므로 안 써도 된다.

📦 예제 : 두 인자의 타입이 다를 때

template <typename T>
bool equal(T a, T b) {
    return a == b;
}

int main() {
    // equal(3, 3.5);       // ❌ 에러: 타입이 다르므로 T를 추론할 수 없음
    equal<double>(3, 3.5); // ✅ double로 명시해주면 OK
}

2-2. Non-type template parameter

템플릿 괄호 < > 안에 숫자(정수) 를 넣는 것.

template <int N>
int scale(int value) {
    return value * N;
}

→ <3>은 N = 3으로 설정하겠다는 뜻이다.
value = 5니까 return 5 * 3 = 15.
즉, <3>은 N이라는 정수 템플릿 인자에 3을 전달한 것이다.


⚠️ 차이점 (template vs parameter)

int scale(double value, int n) {
    return value * n;
}

→ 이렇게 작성해도 되는데 왜 template을 쓰는가?

일반 함수템플릿 함수
코드가 작고 단순타입이나 숫자에 따라 자동으로 여러 함수 생성
변수 값을 받을 수 있음반드시 상수(literal)만 받을 수 있음
실행은 좀 느릴 수 있음실행 빠름 (컴파일 시 최적화됨)
초보자에게 쉬움에러 복잡하고 사용 어렵기도 함

🔚 결론

상황일반 함수템플릿 함수
사용자가 입력한 값으로 계산할 때
타입이 다양하고 코드 재사용하고 싶을 때❌ (중복 많음)
코드가 작고 간단해야 할 때
속도가 아주 중요한 고정 연산일 때


3. default template argument

template <typename T, typename C = std::vector<T>>
T sum1(C c) {
	T t = 0;
	for (const auto& e : c)
		t += e;
	return t;
}

→ return type이 T이고, parameter는 C type의 c를 전달받는, sum1 함수 템플릿을 선언하였다. 템플릿 파라미터 C는 기본값으로 std::vector< T >가 설정되어 있다.



template <typename T, typename C = std::vector<T>>

→ sum1 함수 템플릿은 2개의 타입 인자를 가지며,
두 번째 인자 C는 기본적으로 std::vector< T > 타입을 사용한다.
하지만 일반적으로는 컴파일러가 인자를 추론해 주기 때문에 생략 가능하다.



profile
안녕하세요.

0개의 댓글