Function Template

함수 템플릿은 호출 시점에 타입별 함수를 만든다

템플릿 함수는 하나의 함수처럼 보이지만 실제로는 인자 타입마다 다른 인스턴스를 만든다. 타입 추론과 제약이 오류 메시지의 품질을 좌우한다.

01

추론된 T의 값·참조 형태 확인

값, 참조, const, 배열, 문자열 리터럴이 추론에서 어떻게 변하는지 확인한다.

02

가능한 연산을 제한한다

템플릿 본문에서 쓰는 연산을 concept이나 requires로 먼저 표현한다.

03

오버로드와 맞춘다

일반 함수, 템플릿, 특수화가 함께 있을 때 어떤 후보가 선택되는지 테스트한다.

T
타입 자리표시자 호출 인자의 타입에서 컴파일러가 T를 추론한다.
반환 타입만으로는 보통 추론하지 못한다.
참조
복사 방지와 보존 T&, const T&, T&&는 추론 규칙이 서로 다르다.
forwarding reference는 특히 주의한다.
concept
읽히는 제약 정렬 가능, 더하기 가능 같은 조건을 함수 선언부에 드러낸다.
오류 메시지가 짧아진다.
인스턴스
타입별 코드 사용된 타입 조합마다 함수 본문이 컴파일된다.
헤더에 정의가 있어야 하는 이유다.

추론 확인 · 연산 요구 · 과도한 일반화 점검

추론 확인 const char*, std::string, std::string_view 같은 근접 타입에서 의도대로 고르는가.
연산 요구 본문에서 사용하는 +, <, begin/end가 선언부 제약에 반영되어 있는가.
과도한 일반화 두 타입만 쓴다면 템플릿보다 오버로드가 더 읽기 쉽지 않은가.

제약 있는 템플릿

template <typename T>
requires std::totally_ordered<T>
const T& clamp_value(const T& value, const T& low, const T& high) {
    return std::min(std::max(value, low), high);
        overflow-wrap: break-word;
        word-break: keep-all;
      }