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.