1. 함수 템플릿 (Function Template)

함수 템플릿은 다양한 타입에 대해 동일한 함수 로직을 재사용하기 위해 사용됩니다.

template <typename T>
T add(T a, T b) {
    return a + b;
}

호출 예:

add(3, 4);       // T는 int
add(3.5, 4.2);   // T는 double
add<int>(3, 4);  // 명시적 호출


2. 템플릿 인자 추론

컴파일러는 함수 인자의 타입을 통해 템플릿 인자를 유추합니다. 그러나 반환 타입에만 템플릿 인자가 사용되면, 명시적으로 타입을 지정해야 합니다.

template <typename T>
T identity() {
    return T();
}

identity<int>();  // OK
identity();       // ❌ T를 추론할 수 없음


3. 다중 템플릿 인자와 명시적 타입 지정

템플릿 인자가 복수일 경우, 일부는 추론되고 일부는 명시될 수 있다.

매개변수로 추론할 수 없는 타입이 있다면 명시해주어야한다.

template <typename T, typename A1, typename A2>
T* factory(A1& a1, A2& a2) {
    return new T(a1, a2);
}

int a = 10, b = 20;
factory<MyClass>(a, b);  // T는 명시, A1/A2는 추론


4. 참조 타입과 템플릿

타입 허용 값 종류 수정 가능 여부
T& lvalue only 가능
const T& lvalue + rvalue 불가능
T&& rvalue only 가능
template <typename T>
void modify(T& val) { val += 1; }

modify(10); // ❌ rvalue는 lvalue 참조에 전달 불가

// OK: const 참조는 rvalue 허용
template <typename T>
void print(const T& val) {
    std::cout << val << std::endl;
}

print(10);  // ✅ OK