C ++ 템플릿은 일종의 영광스러운 매크로입니까?


27

C ++ 템플릿과 이와 같은 C # / Java 제네릭 간의 다른 비교에서

https : //.com/questions/31693/what-are-the-differences-between-generics-in-c-and-java-and-templates-in-c/31929#31929

C ++ 템플릿은 컴파일하지 않고 일종의 전처리 (구문 분석하기 전에 일반 텍스트 교체)에 의해 구현된다는 인식을 얻었습니다. C ++ 템플릿의 유형 검사는 C 매크로와 유사하기 때문입니다. 내 말은, 오류가있는 경우 템플릿 자체가 아닌 템플릿 코드 블록을 처리 한 후 생성 된 코드의 오류입니다. 즉, C에서 매크로의 상위 버전 일뿐입니다.

그런 다음 이것을 뒷받침하는 다른 사실을 발견했습니다.

  • 전처리로 C ++ 템플릿을 구현하면 동적 연결 (.dll 사용)에 문제가 있다고 생각했습니다. 그리고 빠른 인터넷 검색이이를 지원했습니다.

  • 또 다른 요점은 정수 상수가 템플릿에 인수로 전달 될 수 있다는 것입니다. 그리고 그것은 어떤 종류의 재귀를 지원합니다. 그러나이 재귀는 컴파일 된 어셈블리 / 머신 코드에서 찾을 수 없습니다. 재귀는 모든 재귀 호출에 대한 함수를 생성하여 더 크지 만 빠른 실행 바이너리를 가지고 컴파일 타임에 관리됩니다.

C 매크로와는 달리 뛰어난 기능을 가지고 있습니다. 그러나 C ++ 템플릿은 어떤 종류의 전처리로 구현되지 않습니까? 이것은 다른 C ++ 컴파일러에서 어떻게 구현됩니까?


19
아니. C ++ 템플릿이 컴파일되었습니다.
Edward Strange

2
"전처리"에 대한 정의는 무엇입니까? 그리고 "컴파일"? "전처리"의 충분히 넓은 정의에는 컴파일러가하는 모든 것이 포함될 수 있습니다. 결국, 컴파일러는 소스가 실행되기 전에 실제로 소스를 처리합니다.
제임스 맥닐리 스

@James McNellis IMHO 전처리를 컴파일을 위해 수행 된 다른 모든 작업과 차별화 할 수 있다면 내 질문을 이해하는 것으로 충분합니다. preprocessor- 명확히 들어 en.wikipedia.org/wiki/Preprocessor#Lexical_preprocessors을
Gulshan

6
이러한 형태의 전처리를 언급한다면 C ++ 템플릿은 단순히 일종의 영광스러운 매크로가 아닙니다.
James McNellis

1
템플릿 언어는 실제로 완성 된 상태이므로 개선 된 매크로 이상의 기능을합니다.
davidk01

답변:


9

C ++ 템플릿은 일종의 멍청한 Lisp (또는 그 이상의 Scheme) 매크로입니다. 컴파일 시간에 평가되는 Turing-complete 언어이지만 해당 언어에서 기본 C ++ 환경으로 액세스 할 수 없으므로 심각하게 제한됩니다. 따라서 C ++ 템플릿은 생성되는 코드와의 상호 작용이 매우 제한적인 일부 전처리 형식으로 볼 수 있습니다.


2
"하지만 해당 언어에서 기본 C ++ 환경으로 액세스 할 수 없으므로 심각하게 제한됩니다." -- 무슨 뜻이에요? 이 문장을 파싱하려고했지만 실패했습니다.
quant_dev

2
음, 사실은 ... github.com/kmichel/bf0x
안톤 Golov

3
@ SK-logic : 따로, C ++ 11 C ++입니다. 다른 언어와 동일한 언어의 다른 버전을 다른 언어로 취급하지 않는 한.
Jon Purdy

3
@ Jon Purdy, C ++ 11 은이 답변 당시까지 공식적으로 존재하지 않았습니다. 오늘날 데이터 구조 분해, 라이브러리 함수 사용 등과 같은 예제가 더 복잡했을 것입니다.
SK-logic

1
@ SK-logic : Lisp와 유사한 매크로로 C ++ 구현을 알고 있습니까? 템플릿 제한으로 인해 어려움을 겪고 있습니다. C ++의 예 - Haxe 강력한 매크로 시스템과 스타일 구문 언어 : haxe.org/manual/macros . (8 비트 마이크로 컨트롤러 프로그래밍; C ++을 그 목적으로 사용하기 때문에 도움이되지 않습니다. 다른 언어에는 더 나은 언어가 있습니다).
pfalcon

41

아마도 가장 큰 차이점은 다른 컴파일을 수행하기 전에 C 매크로가 사전 처리 단계에서 확장되고 C ++ 템플릿은 컴파일의 일부라는 것입니다. 즉, C ++ 템플릿은 무엇보다 유형을 인식하고 범위가 지정되며 단순한 텍스트 대체가 아닙니다. 실제 함수로 컴파일 할 수 있으므로 매크로가 가진 대부분의 문제를 피할 수 있습니다. 유형을 인식한다는 것은 일반적이거나 전문화 될 수 있음을 의미합니다. 예를 들어 swap템플릿 기능 을 제공 하기 쉽고 객체가 힙 메모리를 관리하더라도 잘 작동하는 전문화를 쉽게 작성할 수 있습니다.

따라서 C ++ 템플릿은 매크로와 동일한 의미에서 전처리가 아니며 C 매크로의 종류가 아니며 C 매크로를 사용하여 템플릿의 기능을 복제하는 것은 불가능합니다.

템플릿은 링크 된 라이브러리가 아닌 헤더 파일에 존재하지만 .dll을 제공하는 경우 사용할 헤더 파일도 제공합니다.


12
그들은 헤더 파일에 살 필요가 없습니다 (이를 사용하는 가장 간단한 기술입니다). 소스 파일에서이를 정의하고 소스 파일 (컴파일 단위)에서 템플리트를 수동으로 인스턴스화 할 수 있습니다. 그런 다음 연결하면 인스턴스화가 정상적으로 수행됩니다 (템플릿을 특정 유형으로 제한하고 모든 일반 유형을 허용하지 않는 기술).
Martin York

@Martin :이 기술 (지원되는 동안)이 실제로 표준에서 명시 적으로 지원되는지 확실하지 않습니다. 그렇지 않으면 모든 컴파일러가 export이미 구현 되었을 것 입니다. 나는 그것이 기능에 대한 일종의 작동을 알고 있지만 클래스에 대해서는 작동하지 않을 것이라고 생각합니다.
Matthieu M.

@Matthieu M : 이것은 내보내기 키워드와 관련이 없습니다. "명시 적"템플릿 인스턴스화를 다루며 표준에 잘 정의되어 있습니다.
Martin York

2
@ Matthieu M. : 컴파일러가 함수의 서명을 알고 링커가 구현을 찾을 수 있다면 모든 것이 멋집니다. 함수가 템플릿 함수인지 여부에 적용됩니다. 실제로는 특정 인스턴스화를 강제하는 것이 일반적으로 가치가있는 것보다 더 많은 작업을 수행하기 때문에 헤더 파일에 일반적으로 존재하지만 Martin은 대안에 주목하는 것이 정확합니다.
David Thornley

나는 그것이 특수 기능에 확실히 작동한다는 것을 알고 있습니다. 그러나 나는 그것이 수업에서 작동하지 않는다는 것을 확신합니다. 나는 그것이 특수 클래스의 메소드에서도 작동한다고 생각하지만 이것이 표준인지 아닌지는 모른다.
Matthieu M.

5

구현 방법이 중요합니까? 초기 C ++ 컴파일러는 코드를 ac 컴파일러에 공급 한 프리 프로세서 일 뿐이며 C ++이 단지 영광스러운 매크로라는 의미는 아닙니다.

템플릿은 여러 유형에 대한 코드를 구현하는 더 안전하고 효율적이며 특수한 (실제로 생각하지는 않더라도) 방법을 제공함으로써 매크로의 필요성을 제거합니다.

c에서 템플릿 코드를 작성하는 다양한 방법이 있습니다. 간단한 유형을 넘어 서면 그다지 좋은 방법은 없습니다.


나는 C ++가 영광스러운 매크로라고 말하지 않았습니다. 나는 C ++을 많이 존경한다. 그냥 궁금 해서요
Gulshan

2
@ 굴샨 : 아니, 당신은 그것에 대해 아무 말도하지 않았다. 그럼에도 불구하고, 그것은 초기 C ++ 컴파일러의 작동 방식입니다 (CFront가 매크로 전 처리기 대신 컴파일러의 것임을 제외하고). C ++ 템플릿에 대한 설명은 초기 C ++ 자체에 적용됩니다.
David Thornley

CFront C ++를 C로 컴파일 했습니다. 전처리 기와 컴파일러 사이의 선은 명확하게 정의되어 있습니다. 컴파일러는 구문 분석, AST 빌드 등을 통해 입력을 이해하려고 시도하지만 전처리 기는 텍스트 또는 토큰 대체 만 사용하지 않습니다.
Jon Purdy

1
David가 의미하는 바는 C ++의 기본 하위 집합이 있으며 템플릿은이 하위 집합의 프로그램을 일반화하는 데 사용되는 일종의 매크로로 생각할 수 있으며, 이후 별도의 별도 단계로 컴파일 할 수 있습니다.
Giorgio

5

몇 가지 차이점이 있습니다. 예를 들어, 템플릿을 사용하면 필요할 때 함수 오버로드를 인스턴스화 할 수 있지만 매크로의 경우 가능한 오버로드마다 매크로를 한 번 확장하여 컴파일러에 표시되도록해야하므로 많은 결과를 얻게됩니다. 사용하지 않는 코드

또 다른 차이점은 템플릿이 네임 스페이스를 존중한다는 것입니다.


2

IMHO, C ++ 템플릿 및 C 매크로는 완전히 다른 두 가지 문제를 해결하기위한 것입니다. 원래 C ++ 표준 템플릿 라이브러리는 컨테이너 클래스 (배열, 링크 된 목록 등)를 일반적으로 적용되는 일반 함수 (정렬 및 연결 등)에서 명확하게 분리하는 메커니즘이었습니다. 효율적인 알고리즘과 데이터 구조를 추상적으로 표현하면 특정 표현 데이터에서 작동하는 함수를 가장 잘 구현하는 방법에 대한 추측이 크게 줄어들 기 때문에보다 표현적인 코드가됩니다. C 매크로는 인라인 코드로 언어를 "확장"하는 수단을 제공한다는 점에서 Lisp 매크로에서 일반적으로 볼 수있는 것과 훨씬 더 일치했습니다. 멋진 점은 C ++ 표준 라이브러리가 템플릿 기능을 확장하여 C에서 #define에 사용하는 것의 대부분을 커버한다는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.