콘텐츠로 이동

클래스 템플릿 인자 추론 (Class Template Argument Deduction)

클래스 템플릿 인자 추론은 그것을 지원하기로 명시적으로 선택한 템플릿에만 사용하세요.

정의:

클래스 템플릿 인자 추론(흔히 "CTAD"로 줄여 부릅니다)은 템플릿을 이름으로 지칭하는 타입으로 변수를 선언하면서 템플릿 인자 목록을 (빈 꺾쇠괄호조차) 적지 않을 때 일어납니다.

std::array a = {1, 2, 3};  // `a`는 std::array<int, 3>입니다

컴파일러는 템플릿의 "추론 가이드"를 사용해 초기화식에서 인자를 추론합니다. 추론 가이드는 명시적일 수도 암시적일 수도 있습니다.

명시적 추론 가이드는 후행 반환 타입이 있는 함수 선언처럼 생겼습니다. 다만 앞에 auto가 없고 함수 이름이 템플릿의 이름이라는 점이 다릅니다. 예를 들어 위의 예는 std::array에 대한 다음 추론 가이드에 의존합니다.

namespace std {
template <class T, class... U>
array(T, U...) -> std::array<T, 1 + sizeof...(U)>;
}

(템플릿 특수화가 아닌) 주 템플릿의 생성자들도 추론 가이드를 암시적으로 정의합니다.

CTAD에 의존하는 변수를 선언하면, 컴파일러는 생성자 오버로드 해결 규칙에 따라 추론 가이드를 하나 고르고, 그 가이드의 반환 타입이 변수의 타입이 됩니다.

장점:

CTAD를 쓰면 코드에서 상용구를 생략할 수 있는 경우가 있습니다.

단점:

생성자로부터 생성되는 암시적 추론 가이드는 바람직하지 않게 동작하거나 아예 틀릴 수 있습니다. CTAD가 C++17에 도입되기 전에 작성된 생성자라면 특히 문제가 되는데, 그 생성자를 작성한 사람들은 자기 생성자가 CTAD에서 일으킬 문제를 알 방법이(고칠 방법은 말할 것도 없고) 없었기 때문입니다. 게다가 그 문제를 고치려고 명시적 추론 가이드를 추가하면, 암시적 추론 가이드에 의존하던 기존 코드가 깨질 수 있습니다.

CTAD는 auto가 가진 단점도 상당 부분 그대로 안고 있습니다. 둘 다 변수 타입의 전부 또는 일부를 초기화식에서 추론하는 장치이기 때문입니다. CTAD가 auto보다 독자에게 정보를 더 주기는 하지만, 정보가 생략되었다는 분명한 신호를 주지 않는 것도 마찬가지입니다.

결정:

템플릿 관리자가 명시적 추론 가이드를 하나 이상 제공해 CTAD 사용을 지원하기로 선택하지 않았다면, 그 템플릿에는 CTAD를 사용하지 마세요(std 네임스페이스의 모든 템플릿은 지원을 선택한 것으로 간주합니다). 가능하다면 컴파일러 경고로 이를 강제해야 합니다.

CTAD의 사용은 타입 추론에 대한 일반 규칙도 따라야 합니다.


옮긴이 풀이

핵심: 명시적으로 지원하는 템플릿에만 CTAD

CTAD(클래스 템플릿 인자 추론)는 템플릿 인자 목록 없이 변수를 선언할 때 컴파일러가 인자를 추론하는 기능입니다.

std::array a = {1, 2, 3};  // a는 std::array<int, 3>

규칙

  • 템플릿 작성자가 명시적 추론 가이드(deduction guide)를 제공해 CTAD를 지원하기로 한 템플릿에만 쓰세요. (std 네임스페이스의 템플릿은 지원하는 것으로 간주.)
  • 생성자에서 자동 생성된 암시적 추론 가이드는 부정확하거나 바람직하지 않을 수 있습니다(특히 C++17 이전에 작성된 생성자).
  • CTAD는 auto의 단점도 그대로 가집니다 — 정보가 생략됐다는 단서를 독자에게 주지 않습니다.
  • 사용은 타입 추론의 일반 규칙을 따르세요.