extern 템플릿 사용 (C ++ 11)
그림 1 : 기능 템플릿
TemplHeader.h
template<typename T>
void f();
TemplCpp.cpp
template<typename T>
void f(){
//...
}
//explicit instantation
template void f<T>();
Main.cpp
#include "TemplHeader.h"
extern template void f<T>(); //is this correct?
int main() {
f<char>();
return 0;
}
을 사용하는 올바른 방법입니까 extern template
, 아니면 그림 2에서와 같이 클래스 템플릿에만이 키워드를 사용합니까?
그림 2 : 클래스 템플릿
TemplHeader.h
template<typename T>
class foo {
T f();
};
TemplCpp.cpp
template<typename T>
void foo<T>::f() {
//...
}
//explicit instantation
template class foo<int>;
Main.cpp
#include "TemplHeader.h"
extern template class foo<int>();
int main() {
foo<int> test;
return 0;
}
이 모든 것을 하나의 헤더 파일에 넣는 것이 좋지만 여러 파일에서 동일한 매개 변수로 템플릿을 인스턴스화하면 여러 개의 동일한 정의가 생기고 컴파일러는 오류를 피하기 위해 하나를 제외하고 모두 제거합니다. 어떻게 사용 extern template
합니까? 클래스에만 사용할 수 있습니까, 아니면 함수에도 사용할 수 있습니까?
또한 그림 1과 그림 2는 템플릿이 단일 헤더 파일에있는 솔루션으로 확장 될 수 있습니다. 이 경우 extern template
동일한 인스턴스가 여러 개 발생하지 않도록 키워드를 사용해야합니다 . 이것은 클래스 나 함수에만 해당됩니까?
템플릿이 다른 곳에서 인스턴스화된다는 것을 알고 있을 때 extern template
컴파일러가 템플릿을 인스턴스화 하지 않도록 강제하는 데 에만을 사용해야 합니다 . 컴파일 시간과 개체 파일 크기를 줄이는 데 사용됩니다.
예를 들면 :
// header.h
template<typename T>
void ReallyBigFunction()
{
// Body
}
// source1.cpp
#include "header.h"
void something1()
{
ReallyBigFunction<int>();
}
// source2.cpp
#include "header.h"
void something2()
{
ReallyBigFunction<int>();
}
그러면 다음과 같은 개체 파일이 생성됩니다.
source1.o
void something1()
void ReallyBigFunction<int>() // Compiled first time
source2.o
void something2()
void ReallyBigFunction<int>() // Compiled second time
두 파일이 함께 연결되어 있으면 하나 void ReallyBigFunction<int>()
가 삭제되어 컴파일 시간과 개체 파일 크기가 낭비됩니다.
To not waste compile time and object file size, there is an extern
keyword which makes the compiler not compile a template function. You should use this if and only if you know it is used in the same binary somewhere else.
Changing source2.cpp
to:
// source2.cpp
#include "header.h"
extern template void ReallyBigFunction<int>();
void something2()
{
ReallyBigFunction<int>();
}
Will result in the following object files:
source1.o
void something1()
void ReallyBigFunction<int>() // compiled just one time
source2.o
void something2()
// No ReallyBigFunction<int> here because of the extern
When both of these will be linked together, the second object file will just use the symbol from the first object file. No need for discard and no wasted compile time and object file size.
This should only be used within a project, like in times when you use a template like vector<int>
multiple times, you should use extern
in all but one source file.
This also applies to classes and function as one, and even template member functions.
Wikipedia has the best description
In C++03, the compiler must instantiate a template whenever a fully specified template is encountered in a translation unit. If the template is instantiated with the same types in many translation units, this can dramatically increase compile times. There is no way to prevent this in C++03, so C++11 introduced extern template declarations, analogous to extern data declarations.
C++03 has this syntax to oblige the compiler to instantiate a template:
template class std::vector<MyClass>;
C++11 now provides this syntax:
extern template class std::vector<MyClass>;
which tells the compiler not to instantiate the template in this translation unit.
The warning: nonstandard extension used...
Microsoft VC++ used to have a non-standard version of this feature for some years already (in C++03). The compiler warns about that to prevent portability issues with code that needed to compile on different compilers as well.
Look at the sample in the linked page to see that it works roughly the same way. You can expect the message to go away with future versions of MSVC, except of course when using other non-standard compiler extensions at the same time.
The known problem with the templates is code bloating, which is consequence of generating the class definition in each and every module which invokes the class template specialization. To prevent this, starting with C++0x, one could use the keyword extern in front of the class template specialization
#include <MyClass> extern template class CMyClass<int>;
The explicit instantion of the template class should happen only in a single translation unit, preferable the one with template definition (MyClass.cpp)
template class CMyClass<int>;
template class CMyClass<float>;
If you have used extern for functions before, exactly same philosophy is followed for templates. if not, going though extern for simple functions may help. Also, you may want to put the extern(s) in header file and include the header when you need it.
참고URL : https://stackoverflow.com/questions/8130602/using-extern-template-c11
'program story' 카테고리의 다른 글
Rails : 예외의 전체 스택 추적 로깅 (0) | 2020.08.16 |
---|---|
Javascript에서 정규식 하위 문자열 일치를 어떻게 바꿀 수 있습니까? (0) | 2020.08.16 |
PHP 함수 설명 (0) | 2020.08.16 |
string :: compare가 int를 반환하는 이유는 무엇입니까? (0) | 2020.08.16 |
종속 자식 이미지가있는 Docker 이미지를 삭제할 수 없습니다. (0) | 2020.08.16 |