2010-02-28 9 views
60

몇 주 동안 휴식을 취한 후 책으로 템플릿으로 내 지식을 넓히려 고 노력하고 있습니다. – 완료 안내서 David Vandevoorde 및 Nicolai M. Josuttis가이 순간에 이해하려고하는 내용은 다음과 같습니다. 템플릿의 명시적인 인스턴스화.명시 적 인스턴스화 - 언제 사용됩니까?

실제로 메커니즘과 관련하여 문제가없는 것은 아니지만이 기능을 사용하고자하는 상황을 상상할 수는 없습니다. 누구든지 저에게 그 사실을 설명 할 수 있다면, 나는 감사 할 가치가있을 것입니다.

답변

38

은 직접 http://msdn.microsoft.com/en-us/library/by56e477%28VS.80%29.aspx 기술 :

명시 적 인스턴스화는 당신이 실제로 당신의 코드를 사용하지 않고 템플릿 클래스 또는 함수의 인스턴스를 만들 수 있습니다. 이 템플릿은 템플릿을 사용하는 라이브러리 (.lib) 파일을 만들 때 유용하므로 인스턴스화되지 않은 템플릿 정의는 개체 (.obj) 파일에 저장되지 않습니다.

은 (예를 들어, 된 libstdC++가 std::basic_string<char,char_traits<char>,allocator<char> >의 명시 적 인스턴스 (std::string 인) 당신이 std::string의 기능을 사용할 수 있도록 모든 시간을 포함, 동일한 기능의 코드는 객체에 복사 할 필요가 없습니다. 컴파일러는 필요 libstdC++에 대한 참조 (링크).

+6

그래는 MSVC CRT 라이브러리는 모든 스트림, 로케일 및 문자열 클래스의 명시 적 인스턴스 생성을 전문 char 및 wchar_t. 결과 .lib는 5 메가 바이트 이상입니다. –

+2

컴파일러는 템플릿이 다른 곳에서 명시 적으로 인스턴스화되었음을 어떻게 알 수 있습니까? 클래스 정의가 생성 되었기 때문에 클래스 정의를 생성하지 않습니까? –

+0

@STing : 템플릿이 인스턴스화되면 심볼 테이블에 해당 함수가 입력됩니다. – kennytm

50

명시 적으로 몇 가지 유형에 대해서만 작업하려는 템플릿 클래스를 정의하는 경우.

일반 클래스처럼 헤더 파일에 템플릿 선언을 넣습니다.

템플릿 정의를 일반 클래스처럼 소스 파일에 넣으십시오.

그런 다음 소스 파일의 끝에서 사용 가능하게하려는 버전 만 명시 적으로 인스턴스화하십시오.

바보 예 :

// StringAdapter.h 
template<typename T> 
class StringAdapter 
{ 
    public: 
     StringAdapter(T* data); 
     void doAdapterStuff(); 
    private: 
     std::basic_string<T> m_data; 
}; 
typedef StringAdapter<char> StrAdapter; 
typedef StringAdapter<wchar_t> WStrAdapter; 

출처 :

// StringAdapter.cpp 
#include "StringAdapter.h" 

template<typename T> 
StringAdapter<T>::StringAdapter(T* data) 
    :m_data(data) 
{} 

template<typename T> 
void StringAdapter<T>::doAdapterStuff() 
{ 
    /* Manipulate a string */ 
} 

// Explicitly instantiate only the classes you want to be defined. 
// In this case I only want the template to work with characters but 
// I want to support both char and wchar_t with the same code. 
template class StringAdapter<char>; 
template class StringAdapter<wchar_t>; 

홈페이지

#include "StringAdapter.h" 

// Note: Main can not see the definition of the template from here (just the declaration) 
//  So it relies on the explicit instantiation to make sure it links. 
int main() 
{ 
    StrAdapter x("hi There"); 
    x.doAdapterStuff(); 
} 
+1

컴파일러가 주어진 변환 단위에서 전체 템플릿 정의 (함수 정의 포함)를 가지면 * 필요할 때 템플릿의 특수화를 인스턴스화합니다 (해당 전문 분야가 다른 TU에서 명시 적으로 인스턴스화되었는지 여부는 관계 없음). 즉, 명시 적 인스턴스화의 컴파일/링크 타임 이점을 얻으려면 컴파일러가 인스턴스화 할 수 없도록 템플릿 * 선언 * 만 포함해야합니다. –

+1

@ user123456 : 아마 컴파일러에 의존합니다. 그러나 대부분의 상황에서 그렇다. –

+1

거기에 컴파일러가 미리 지정한 유형에 대해이 명시 적으로 인스턴스화 된 버전을 사용하도록하는 방법이 있지만 "이상한/예기치 않은"유형으로 템플릿을 인스턴스화하려고하면 "정상적으로"작동하게합니다. 필요에 따라 템플릿을 인스턴스화합니까? –

관련 문제