C++에서 템플릿 클래스를 사용하는 경우라면 구현이 헤더 파일에 있거나 헤더 파일의 하단에 # 포함되어 있어야합니다.C++ templates : 헤더 파일이 여전히 손상 되었습니까?
저는 C++ 템플릿을 몇 년 동안 사용하지 않았습니다. 방금 다시 사용하기 시작한 후이 동작이 인 것처럼 보일 경우이 지속되는 것으로 나타났습니다. 아직도 그렇습니까? 또는 컴파일러가 구현을 인터페이스와 분리하여 충분히 스마트하게 만들었습니까?
C++에서 템플릿 클래스를 사용하는 경우라면 구현이 헤더 파일에 있거나 헤더 파일의 하단에 # 포함되어 있어야합니다.C++ templates : 헤더 파일이 여전히 손상 되었습니까?
저는 C++ 템플릿을 몇 년 동안 사용하지 않았습니다. 방금 다시 사용하기 시작한 후이 동작이 인 것처럼 보일 경우이 지속되는 것으로 나타났습니다. 아직도 그렇습니까? 또는 컴파일러가 구현을 인터페이스와 분리하여 충분히 스마트하게 만들었습니까?
선언과 구현을 구분하기 위해 표준에서는 사용자가 내보내기 키워드를 사용해야합니다. 내가 아는 한, 그것을 처리하는 방법을 알고있는 컴파일러는 오직 하나뿐입니다 .Comeau.
그러나 C++ 0x에는 특정 전문화를 자동으로 인스턴스화하지 않도록 컴파일러에 알리는 메커니즘 (extern templates)이 포함됩니다. 따라서 컴파일 시간을 줄이려면 특정 컴파일 단위에서 일부 전문을 명시 적으로 인스턴스화하고 헤더에서 extern으로 선언하여 컴파일 시간을 단축 할 수 있습니다.
(export
키워드 사용) 템플릿은 Comeau C++ (: C++ FAQ Lite)에 의해서만 지원되는 것으로 보이는 템플릿입니다.
구현 코드가없는 인터페이스를 유지하는 일반적인 기술은 인라인 함수 정의를 선언 헤더의 끝에 포함 할 수있는 별도의 "구현"헤더에 넣는 것입니다.
솔직히 말하면, 나는 수출을 찾고있는 것이 아닙니다. 다른 언어 기능과 마찬가지로 템플릿 내부에 템플릿 구현을 포함하지 않아도되는 헤더를 찾고있었습니다. –
수출은 EDG 프론트 엔드에 의해서만 지원되며, 상업적으로는 내가 알고있는 한 Comeau 컴파일러에서만 사용할 수 있습니다.
내보내기는 컴파일러 작성자의 막대한 노력이 필요하지만 소스 공개가 필요 없으며 컴파일 종속성도 줄이지 않습니다.
그래서 Herb Sutter는 컴파일러 빌더에게 '내보내기를 잊어라'고 물었습니다. 필요한 시간 투자가 다른 곳에서 쓰는 것이 더 좋을 것이므로 ... 얼마나 오랜 시간이 걸리고 얼마를 얻은지를 본 후에 다른 컴파일러가 수출을 구현할 것이라고 생각하지 않습니다.
이 논문은 "왜 우리가 수출 할 여력이 없는가?"라고 말하면서 Sutters blog에 있지만 PDF는 없다. (빠른 구글이 그것을 만들어야한다.) 6 년 전, 나는 그들이 모두 듣고 방해 :
많은 사람들이 두 개의 헤더 파일 (예를 들어 .hpp
및 .ipp
) 만 선언 하나, 그리고 정의에 하나를 사용 그것은 단순히 다른 하나를 포함하는 문제입니다.
foo.hpp
#ifndef MY_TEMPLATES_HPP
#define MY_TEMPLATES_HPP
template< class T >
void foo(T & t);
#include "foo.ipp"
#endif
foo.ipp
#ifdef MY_TEMPLATES_IPP
nonsense here, that will generate compiler error
#else
#define MY_TEMPLATES_IPP
template< class T >
void foo(T & t) {
... // long function
}
#endif
이 단지 이익 물론 일부 선명도는 아무것도 정말 단순히 하나 개의 헤더 파일에 모든 인라인 비교되지 변경합니다.
당신이 참조한 PDF 파일을 찾았습니다 : http://ra.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1426.pdf, 2003 년 3 월 일자 –
@Matthieu M. : PDF가 깨졌습니다. 더 나은 원본 가져 오기 : http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1426.pdf – paercebal
@paercebal : 감사합니다! –
기술적으로 그들은 이 아니며 헤더 파일에이 필요합니다.
이 사용 예는 고정 된 버전 세트가있는 템플릿 클래스가있는 경우입니다 (인수 sake char 및 wchar_t). 그런 다음 모든 메소드를 소스 파일에 넣고이 두 버전을 명시 적으로 인스턴스화 할 수 있습니다.이것은 다른 사람들이 사용할 의도가없는 유형의 템플릿을 조정할 수없는 안전성을 가지고 있습니다. (이 배포가 제공되지 않기 때문에)
// X.h
template<typename T>
class X
{
// DECLARATION ONLY OF STUFF
public:
X(T const& t);
private:
T m_t;
};
// X.cpp
#include "X.h"
// DEFINTION OF STUFF
template<typename T>
X<T>::X(T const& t)
:m_t(t)
{}
// INSTANCIATE The versions you want.
template class X<char>;
template class X<wchar_t>;
// Main.cpp
#include "X.h"
int main()
{
X<chat> x1('a');
X<wchar_t> x2(L'A');
// X<int> x3(5); // Uncomment for a linker failure.
}
가정 사람들은 직접 X.cpp을 포함 할 수 없습니다 다음 다른 X < INT> 또는 X < 플로트> 등 그러나 abovr 클래스가 완전히 있습니다을 사용할 수 없습니다 한정된.
나는 또한이 기술을 사용하여 컴파일 시간을 줄이는 것을 보았다. 각 컴파일 단위가 동일한 버전의 X를 다시 생성하지 않기 때문에 한 곳에서 정의 만 얻을 수 있습니다 (따라서 하나의 컴파일 비용). 이 크기로 축소하면 사용하는 각 X 버전의 X를 수동으로 설치해야합니다.
이것은 내가 필요한 것을하지는 않지만 꽤 개성이있다. 나는 그것을 기억할 것이다. –
GCC는 모든 템플릿을 명시 적으로 인스턴스화하지 않는 한 긴 수집 단계를 거칩니다. VC++는 대처하고있는 것처럼 보입니다.하지만 어쨌든이 단계를 피하는 것이 더 좋습니다. 템플릿을 어떻게 사용할 것인지를 알고 싶습니다. 일반적으로 응용 프로그램의 경우가 아니라 라이브러리의 경우가 많기 때문에 템플릿 정의를 별도의 파일에 저장합니다. 또한 선언을 구현 세부 사항에 덜 복잡하게 만들어 코드를보다 쉽게 읽을 수 있습니다.
내보내기를 사용하더라도 소스를 공개하지 않아도됩니다 (어떤 형식이든). ".et 파일은 프런트 엔드에게 내 보낸 템플릿 정의의 위치 만 알려주고 실제로 정의를 포함하지는 않으므로 내 보낸 템플릿 정의가 포함 된 소스는 인스턴스화시 사용할 수 있어야합니다 (일반적으로 * 특히, 내보내기 기능은 소스 형식으로 템플릿 정의를 게시하지 않기위한 메커니즘이 아닙니다. "(강조 표시) –
@litb : 자극적입니다. 그러나 당신의 대답에 감사드립니다. –
나는 실제로 컴파일러를 구현하지 않았기 때문에 나는 그것을 말하는 위치에 있지 않다. 그러나 나는 EDG의 창조자를 믿는다. –