Class template
클래스 템플릿은 클래스들의 패밀리를 정의합니다.
목차 |
구문
template
<
parameter-list
>
class-declaration
|
(1) | ||||||||
template
<
parameter-list
>
requires
constraint
class-declaration
|
(2) | (C++20부터) | |||||||
export
template
<
parameter-list
>
class-declaration
|
(3) | (C++11에서 제거됨) | |||||||
설명
| class-declaration | - | 클래스 선언 . 선언된 클래스 이름은 템플릿 이름이 됩니다. |
| parameter-list | - | 쉼표로 구분된 비어 있지 않은 템플릿 매개변수 목록으로, 각 매개변수는 상수 매개변수 , 타입 매개변수 , 템플릿 매개변수 , 또는 이들 중 하나의 매개변수 팩 입니다. |
| constraint | - | 이 클래스 템플릿이 수용하는 템플릿 매개변수를 제한하는 제약 조건 표현식 |
export
는 템플릿을
내보내진(exported)
것으로 선언하는 선택적 수정자였습니다(클래스 템플릿과 함께 사용될 경우, 모든 멤버들도 내보내진 것으로 선언했습니다). 내보내진 템플릿을 인스턴스화하는 파일들은 그 정의를 포함할 필요가 없었습니다: 선언만으로 충분했습니다.
export
의 구현체들은 드물었고 세부 사항에 대해 서로 일치하지 않았습니다.
|
(C++11까지) |
클래스 템플릿 인스턴스화
클래스 템플릿 자체는 타입, 객체 또는 다른 어떤 엔티티도 아닙니다. 템플릿 정의만 포함하는 소스 파일로부터는 어떤 코드도 생성되지 않습니다. 코드가 나타나려면 템플릿이 인스턴스화되어야 합니다: 컴파일러가 실제 클래스(또는 함수 템플릿의 경우 함수)를 생성할 수 있도록 템플릿 인자가 제공되어야 합니다.
명시적 인스턴스화
template
class-key
template-name
<
argument-list
>
;
|
(1) | ||||||||
extern
template
class-key
template-name
<
argument-list
>
;
|
(2) | (C++11부터) | |||||||
| class-key | - |
class
,
struct
또는
union
|
명시적 인스턴스 정의는 해당 클래스, 구조체 또는 공용체의 인스턴스화를 강제합니다. 템플릿 정의 이후 프로그램 어디에서나 나타날 수 있으며, 주어진 argument-list 에 대해서는 전체 프로그램에서 단 한 번만 나타날 수 있으며, 진단 메시지는 필요하지 않습니다.
|
명시적 인스턴스화 선언(extern template)은 암시적 인스턴스화 단계를 건너뜁니다: 암시적 인스턴스화를 유발하는 코드는 대신 다른 곳에서 제공된 명시적 인스턴스화 정의를 사용합니다(해당 인스턴스화가 존재하지 않으면 링크 오류가 발생합니다). 이를 사용하여 템플릿 인스턴스화를 사용하는 모든 소스 파일 중 하나를 제외한 파일에서 명시적으로 선언하고, 나머지 파일에서 명시적으로 정의함으로써 컴파일 시간을 줄일 수 있습니다. |
(since C++11) |
클래스, 함수 , 변수 (since C++14) , 그리고 멤버 템플릿 특수화는 해당 템플릿으로부터 명시적으로 인스턴스화될 수 있습니다. 클래스 템플릿의 멤버 함수, 멤버 클래스, 그리고 정적 데이터 멤버는 해당 멤버 정의로부터 명시적으로 인스턴스화될 수 있습니다.
명시적 인스턴스화는 한정된 ID를 사용하지 않는 한, 템플릿의 포함 네임스페이스 내에서만 나타날 수 있습니다:
namespace N { template<class T> class Y // 템플릿 정의 { void mf() {} }; } // template class Y<int>; // 오류: 전역 네임스페이스에서 클래스 템플릿 Y가 보이지 않음 using N::Y; // template class Y<int>; // 오류: 템플릿의 네임스페이스 외부에서의 명시적 인스턴스화 // 템플릿의 네임스페이스 외부에서의 명시적 인스턴스화 template class N::Y<char*>; // OK: 명시적 인스턴스화 template void N::Y<double>::mf(); // OK: 명시적 인스턴스화
명시적 인스턴스화는 동일한 템플릿 인자 집합에 대해 명시적 특수화 가 이미 존재한 경우 아무런 효과가 없습니다.
함수 템플릿을 명시적으로 인스턴스화할 때는 선언만이 가시적으로 필요합니다 , 변수 템플릿 (C++14부터) , 클래스 템플릿의 멤버 함수 또는 정적 데이터 멤버, 또는 멤버 함수 템플릿의 경우에도 마찬가지입니다. 클래스 템플릿, 클래스 템플릿의 멤버 클래스, 또는 멤버 클래스 템플릿을 명시적으로 인스턴스화하기 전에는 완전한 정의가 나타나야 합니다. 단, 동일한 템플릿 인자를 가진 명시적 특수화가 이전에 나타난 경우는 예외입니다.
함수 템플릿 , 변수 템플릿 (since C++14) , 멤버 함수 템플릿, 또는 클래스 템플릿의 멤버 함수나 정적 데이터 멤버가 명시적 인스턴스 정의로 명시적으로 인스턴스화되는 경우, 템플릿 정의는 동일한 번역 단위에 존재해야 합니다.
명시적 인스턴스화가 클래스 템플릿 특수화를 지정할 때, 이는 번역 단위에서 이전에 명시적으로 특수화되지 않은 비상속 비템플릿 멤버 각각에 대한 동일한 종류(선언 또는 정의)의 명시적 인스턴스화 역할을 합니다. 이 명시적 인스턴스화가 정의인 경우, 이 시점에서 정의된 멤버들에 대해서만 명시적 인스턴스화 정의이기도 합니다.
명시적 인스턴스화 정의는 멤버 접근 지정자를 무시합니다: 매개변수 타입과 반환 타입이 private일 수 있습니다.
암시적 인스턴스화
코드가 완전히 정의된 타입을 요구하는 상황에서 템플릿을 참조하거나, 타입의 완전성이 코드에 영향을 미치며, 이 특정 타입이 명시적으로 인스턴스화되지 않은 경우 암시적 인스턴스화가 발생합니다. 예를 들어, 이 타입의 객체가 생성될 때 발생하지만, 이 타입에 대한 포인터가 생성될 때는 발생하지 않습니다.
이는 클래스 템플릿의 멤버들에게 적용됩니다: 멤버가 프로그램에서 사용되지 않는 한, 인스턴스화되지 않으며 정의를 요구하지 않습니다.
template<class T> struct Z // 템플릿 정의 { void f() {} void g(); // 정의되지 않음 }; template struct Z<double>; // Z<double>의 명시적 인스턴스화 Z<int> a; // Z<int>의 암시적 인스턴스화 Z<char>* p; // 여기서는 아무것도 인스턴스화되지 않음 p->f(); // Z<char>와 Z<char>::f()의 암시적 인스턴스화가 여기서 발생함 // Z<char>::g()는 절대 필요하지 않으며 인스턴스화되지 않음: // 정의될 필요가 없음
클래스 템플릿이 인스턴스화 지점에서 선언되었지만 정의되지 않은 경우, 인스턴스화는 불완전한 클래스 타입을 생성합니다:
template<class T> class X; // 선언, 정의가 아님 X<char> ch; // 오류: 불완전한 타입 X<char>
| 지역 클래스 및 해당 멤버에서 사용되는 모든 템플릿은 지역 클래스나 열거형이 선언된 엔티티의 인스턴스화 과정의 일부로 인스턴스화됩니다. | (C++17부터) |
키워드
export (C++11까지) extern (C++11부터)
참고 항목
- 템플릿 매개변수와 인수 는 템플릿을 매개변수화할 수 있게 합니다
- 함수 템플릿 선언 은 함수 템플릿을 선언합니다
- 템플릿 특수화 는 특정 타입에 대해 기존 템플릿을 정의합니다
- 매개변수 팩 은 템플릿에서 타입 목록의 사용을 허용합니다 (C++11부터)