본문으로 바로가기

C++11) extern template

category C++/Modern 2019. 2. 13. 01:59

<개요>


extern template 은 C++11 에서 컴파일 기능 향상을 위해 등장했으며, 같은 템플릿 객체가 2번 이상 인스턴스화 되어

컴파일 시간 및 오브젝트 크기가 증가하는 것을 막아줍니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// header.h
 
template<typename T>
void ReallyBigFunction()
{
    // 뭔가 엄청 길고 큰 작업이 작성돼있음
}
 
// source1.cpp
 
#include "header.h"
void something1()
{
    ReallyBigFunction<int>();
}
 
// source2.cpp
 
#include "header.h"
void something2()
{
    ReallyBigFunction<int>();
}
cs

1
2
3
4
5
6
7
source1.o    
    void something1()
    void ReallyBigFunction<int>()    // 첫번째로 컴파일됨
 
source2.o
    void something2()
    void ReallyBigFunction<int>()    // 두번째로 컴파일됨
cs

something1과 something2의 파일이 링크되면 void ReallyBigFunction<int>() 가 삭제되어 컴파일 시간과 객체 크기가 낭비됩니다. ( 다른 cpp 이므로 )
어짜피 같은 내용으로 작성될 것이라면, 한번만 링크하게 하여 모든곳에서 사용할 수 있게 하자는 것입니다.
그때 사용하는게 template에 대한 extern 키워드인데 이것은 한 template 소스가 다른 곳에서 동일하게 작성되었을때 사용해야 합니다.

1
2
3
4
5
6
7
8
// source2.cpp
 
#include "header.h"
extern template void ReallyBigFunction<int>();    //source2.cpp 를 이렇게 변경 그럼 한번만 컴파일 합니다. (전역적)
void something2()
{
    ReallyBigFunction<int>();        
}
cs

1
2
3
4
5
6
7
source1.o
    void something1()
    void ReallyBigFunction<int>() // 한번만 컴파일 됩니다.
 
source2.o
    void something2()
    //  ReallyBigFunction<int> 는 여기 없습니다. 왜냐면 extern으로 선언됐거든요.
cs

두 파일이 함께 링크될때, 두 번째 파일은 첫 번째 파일의 심볼( 선언 )을 사용합니다. 버릴 필요가 없고 객체 크기가 낭비되지 않습니다.
이것은 vector<int>와 같은 템플릿을 여러번 사용할때처럼 한 프로젝트 내에서만 사용해야 합니다. 
한 소스만을 놔두고 나머지 소스는 extern으로 처리해야 합니다.
이는 클래스 및 함수를 하나의 함수로, 그리고 템플릿도 작동합니다.

1
2
template class CMyClass<int>;
template class CMyClass<float>;
cs

자료형이 다를땐 엄연히 다른 코드입니다. float를 사용하기위해 int를 extern 하셔선 안됩니다.

정보 : https://code-examples.net/ko/q/7c102a