범용 프로그래밍
Generic programming프로그래밍 패러다임 |
---|
범용 프로그래밍은 알고리즘이 나중에 특정 유형으로 작성되어 파라미터로 제공되는 특정 유형에 대해 필요할 때 인스턴스화되는 컴퓨터 프로그래밍 스타일입니다.1973년 [1][2]ML 프로그래밍 언어에 의해 개척된 이 접근방식은 사용 시 동작하는 유형의 집합에서만 다른 공통 함수 또는 유형을 작성할 수 있도록 하여 중복을 줄입니다.이러한 소프트웨어 엔티티는 Ada, C#, Delphi, Eiffel, F#, Java, Nim, Python, Go, Rust, Swift, TypeScript 및 Visual Basic에서는 제네릭이라고 불립니다.NET. ML, Scala, Julia 및 Haskell에서는 파라메트릭 다형성(Haskell 커뮤니티에서는 관련되지만 다소 다른 개념에 대해 "일반적"이라는 용어를 사용), C++ 및 D에서는 템플릿, 영향력 있는 1994년 책 디자인 [3]패턴에서는 파라미터화된 유형으로 알려져 있습니다.
용어는"제네릭 프로그래밍"는 원래 데이비드 Musser과 알렉산더 Stepanov[4]에 의해 상기보다 더 특정한 의미에서, 종류에 근본적인 요건 알고리즘 및 데이터 구조에 구체적인 사례들에서 개념으로서, 일반적인 기능 impleme과 규격화된 개념은 프로그래밍 패러다임을 설명할 말이 만들어졌다.nted 이러한 개념의 관점에서, 일반적으로 위에서 설명한 것과 같은 언어 일반성 메커니즘을 사용한다.
Stepanov – Musser 및 기타 범용 프로그래밍 패러다임
범용 프로그래밍은 Musser & Stepanov(1989)에서 다음과 같이 정의되어 있습니다.
범용 프로그래밍은 다양한 유용한 소프트웨어를 만들기 위해 다양한 데이터 표현과 결합할 수 있는 범용 알고리즘을 얻기 위해 구체적이고 효율적인 알고리즘에서 추상화하는 아이디어를 중심으로 합니다.
--
"일반 프로그래밍" 패러다임은 추상 대수학의 대수 이론의 추상화와 유사하게 알고리즘과 데이터 구조의 구체적인 예에서 유형에 대한 기본 요건을 추상화하고 개념으로 공식화하는 소프트웨어 분해 접근법이다.[6]가장 잘 알려진 예는 표준 템플릿 라이브러리(STL)[8][9]이지만, 이 프로그래밍 접근법의 초기 예는 Scheme와 Ada에서 [7]구현되었다. STL은 데이터 구조 및 이들 구조에서 작동하는 알고리즘을 분리하는 데 사용되는 반복자의 이론을 개발했다.
예를 들어, N개의 시퀀스 데이터 구조(예: 단일 링크 리스트, 벡터 등)와 이에 대해 동작하는 M개의 알고리즘(예:find
,sort
직접 접근방식은 각 데이터 구조에 대해 각 알고리즘을 구현하여 구현해야 할 N × M 조합을 제공한다.그러나, 범용 프로그래밍 어프로치에서는, 각 데이터 구조는, 반복자 개념의 모델(현재치를 취득하기 위해서 참조할 수 있는 단순한 값 타입, 또는 시퀀스내의 다른 값을 가리키도록 변경할 수 있는 단순한 값 타입)을 되돌리고, 대신에, 각 알고리즘은, 그러한 반복자의 인수, 예를 들면 1쌍의 반복자 포인트로 범용적으로 기술된다.처리할 후속 또는 범위의 시작과 끝을 나타냅니다.따라서 N + M 데이터 구조-알고리즘 조합만 구현하면 됩니다.STL에는 몇 가지 반복기 개념이 명시되어 있으며, 각각은 보다 제한적인 개념의 정교화이다. 예를 들어 순방향 반복기는 시퀀스의 다음 값(예: 단일 링크 목록 또는 입력 데이터 스트림에 적합한)으로 이동만 제공하는 반면, 랜덤 액세스 반복기는 시퀀스의 모든 요소에 대한 직접 상수 시간 액세스를 제공한다.(예를 들어 벡터에 적합).중요한 점은 데이터 구조가 효율적으로 구현될 수 있는 가장 일반적인 개념의 모델을 반환한다는 것입니다. 계산 복잡성 요건은 개념 정의의 일부입니다.이로 인해 특정 알고리즘을 적용할 수 있는 데이터 구조가 제한되고 이러한 복잡성 요건이 데이터 구조 선택의 주요 결정 요인입니다.일반 프로그래밍은 그래프 [10]알고리즘과 같은 다른 영역에서도 비슷하게 적용되었다.
이 접근방식은 컴파일 시간 일반성/템플릿의 언어 기능을 사용하는 경우가 많지만 실제로는 특정 언어-기술 세부사항과는 무관합니다.범용 프로그래밍의 선구자 알렉산더 스테파노프는 이렇게 말했다.
범용 프로그래밍은 알고리즘과 데이터 구조를 추상화하고 분류하는 것입니다.그것은 유형 이론에서가 아니라 크누스에서 영감을 얻습니다.그 목적은 유용하고 효율적이며 추상적인 알고리즘과 데이터 구조의 체계적인 카탈로그를 점진적으로 구축하는 것입니다.그런 일은 아직 꿈이다.
--
나는 반복자 이론이 수학의 중심인 것처럼 컴퓨터 과학의 중심이라고 믿는다.
--
비야른 스트루스트럽은 이렇게 말했다.
Stepanov에 이어 언어 기능에 대해 언급하지 않고 범용 프로그래밍을 정의할 수 있습니다.알고리즘과 데이터 구조를 구체적인 예에서 가장 일반적이고 추상적인 형태로 끌어올립니다.
--
일반 프로그래밍으로 설명된 다른 프로그래밍 패러다임으로는 "일반 프로그래밍 – 소개"[14]에서 설명한 데이터 유형 일반 프로그래밍이 있습니다.보일러 플레이트 스크랩 접근법은 Haskell을 [15]위한 경량 범용 프로그래밍 접근법입니다.
이 기사에서는 위의 일반 프로그래밍의 고급 프로그래밍 패러다임을 구현에 사용되는 하위 수준의 프로그래밍 언어 일반성 메커니즘과 구별한다(일반성을 위한 프로그래밍 언어 지원 참조).범용 프로그래밍 패러다임에 대한 자세한 설명 및 비교는 [16]를 참조하십시오.
범용성을 위한 프로그래밍 언어 지원
제네리시티 기능은 적어도 1970년대부터 ML, CLU, Ada 등의 언어로 상위 레벨의 언어로 존재해 왔으며, 이후 베타, C++, D, 에펠, 자바, DEC의 현재는 사용되지 않는 트렐리스올 언어 등 많은 객체 기반 및 객체 지향 언어에 채택되었습니다.
일반성은 다양한 프로그래밍 언어에서 다르게 구현되고 지원되며, "일반성"이라는 용어는 다양한 프로그래밍 컨텍스트에서 다르게 사용되어 왔습니다.예를 들어 Fourth에서는 컴파일러가 컴파일 중에 코드를 실행할 수 있으며 새로운 컴파일러 키워드와 그 단어에 대한 새로운 구현을 즉시 작성할 수 있습니다.컴파일러의 동작을 나타내는 단어는 거의 없기 때문에 대부분의 포스 텍스트에서는 그렇게 언급되지 않는 범용성을 자연스럽게 제공합니다.마찬가지로 동적 유형 언어, 특히 해석된 언어들은 일반적으로 함수에 대한 전달 값과 값 할당 모두 유형으로 구분되며 이러한 동작은 종종 추상화 또는 코드 테르센스에 이용되지만 동적 유형의 직접적인 결과이기 때문에 일반적으로 일반성이라는 레이블이 붙지 않습니다.ping 시스템을 [citation needed]사용합니다.이 용어는 기능 프로그래밍, 특히 하스켈어족 언어에서 사용되어 왔습니다.하스켈어족 언어에서는 유형이 항상 파라메트릭이고 이러한 유형의 실제 코드가 일반인 구조 유형 시스템을 사용합니다.이러한 사용법은 여전히 코드 저장과 추상화 렌더링이라는 유사한 목적을 가지고 있습니다.
배열 및 구조는 미리 정의된 일반 유형으로 볼 수 있습니다.배열 또는 구조 유형을 사용할 때마다 새로운 콘크리트 유형이 인스턴스화되거나 이전에 인스턴스화된 유형이 재사용됩니다.배열 요소 유형 및 구조 요소 유형은 매개 변수화된 유형으로, 해당하는 일반 유형을 인스턴스화하는 데 사용됩니다.이 모든 것은 보통 컴파일러에 내장되어 있으며 구문은 다른 일반적인 구성 요소와 다릅니다.일부 확장 가능한 프로그래밍 언어는 내장형 및 사용자 정의 범용 유형을 통합하려고 합니다.
다음으로 프로그래밍 언어의 일반성 메커니즘에 대한 광범위한 조사를 실시합니다.범용 프로그래밍에 대한 메커니즘의 적합성을 비교하는 구체적인 조사는 [17]를 참조하십시오.
객체 지향 언어
정적으로 입력된 언어로 컨테이너 클래스를 만들 때 포함된 각 데이터 유형에 대해 특정 구현을 작성해야 하는 불편함이 있습니다. 특히 각 데이터 유형의 코드가 사실상 동일한 경우 더욱 그렇습니다.예를 들어 C++에서는 클래스 템플릿을 정의함으로써 이러한 코드 중복을 회피할 수 있습니다.
템플릿< >타이프네임 T> 학급 목록. { // 클래스 내용. }; 목록.< >동물> 목록_of_interface; 목록.< >차> 차량 목록;
위에,T
는 목록 작성 시 지정된 모든 유형의 플레이스 홀더입니다.일반적으로 템플릿이라고 불리는 이러한 "containers-of-type-T"를 사용하면 하위 유형 및 서명과 같은 특정 계약이 유지되는 한 클래스를 다른 데이터 유형으로 재사용할 수 있습니다.이 일반성 메커니즘은 교환 가능한 하위 클래스의 알고리즘 사용인 포함 다형성과 혼동해서는 안 됩니다. 예를 들어 유형의 객체 목록입니다.Moving_Object
타입의 오브젝트를 포함하는 모습Animal
그리고.Car
템플릿은 에서와 같이 타입에 의존하지 않는 기능에도 사용할 수 있습니다.Swap
다음 예:
// "&"는 참조를 나타냅니다. 템플릿< >타이프네임 T> 무효 바꾸다(T& a, T& b) { // 유사하지만 안전하며 잠재적으로 더 빠른 기능 // 표준 라이브러리 헤더에 정의되어 있습니다.< > T 임시직 = b; b = a; a = 임시직; } 표준::스트링 세계 = "세상!"; 표준::스트링 안녕 = "안녕하세요"; 바꾸다(세계, 안녕); 표준::외치다 << > 세계 << > 안녕 << > ‘\n’; // 출력은 "Hello, World!" 입니다.
C++template
위에서 사용된 구성은 프로그래머와 언어 디자이너들 사이에서 개념을 대중화하고 많은 일반적인 프로그래밍 숙어를 지원하는 일반성 구조로서 널리[citation needed] 인용된다.D프로그래밍 언어에서는 C++의 선례를 바탕으로 구문을 단순화한 완전한 범용 대응 템플릿도 제공됩니다.Java 프로그래밍 언어는 J2SE 5.0이 도입된 이후 C++를 기반으로 구문적으로 일반성 기능을 제공해 왔습니다.
C# 2.0, Oxygene 1.5(크롬이라고도 함) 및 Visual Basic.NET 2005 에는, Microsoft 에 있는 범용 디바이스의 서포트를 활용하는 구조가 있습니다.버전 2.0 이후의 NET Framework.
에이다의 제네릭스
아다는 1977년부터 1980년까지 처음 디자인된 이래 제네릭스를 가지고 있다.표준 라이브러리는 제네릭스를 사용하여 많은 서비스를 제공합니다.Ada 2005는 C++의 표준 템플릿 라이브러리에서 영감을 얻은 포괄적인 범용 컨테이너 라이브러리를 표준 라이브러리에 추가합니다.
범용 유닛은 하나 이상의 일반적인 형식 파라미터를 사용하는 패키지 또는 하위 프로그램입니다.
범용 형식 파라미터는 값, 변수, 상수, 유형, 서브프로그램 또는 다른 지정된 범용 유닛의 인스턴스입니다.일반적인 형식 유형의 경우 구문은 이산, 부동 소수점, 고정 소수점, 액세스(포인터) 유형 등을 구분합니다.일부 형식 매개 변수에는 기본값을 지정할 수 있습니다.
범용 유닛을 인스턴스화하기 위해 프로그래머는 각 포멀의 실제 파라미터를 전달합니다.그러면 일반 인스턴스는 다른 유닛과 동일하게 동작합니다.루프 내부 등 런타임에 범용 유닛을 인스턴스화할 수 있습니다.
예
범용 패키지의 사양:
포괄적인 최대_사이즈 : 자연의; --일반적인 형식 값 유형 요소_유형 이 사적인; --일반적인 형식. 제한되지 않는 모든 형식을 받아들입니다. 패키지 스택 이 유형 사이즈_타입 이 범위 0 .. 최대_사이즈; 유형 스택 이 한정된 사적인; 절차. 만들다 (S :나가. 스택; Initial_Size(초기 사이즈) :에 사이즈_타입 := 최대_사이즈); 절차. 밀다 (안으로 :에 나가. 스택; 요소 :에 요소_유형); 절차. 팝 (부터 :에 나가. 스택; 요소 :나가. 요소_유형); 오버플로 : 예외.; 언더플로우 : 예외.; 사적인 서브타입 인덱스_타입 이 사이즈_타입 범위 1 .. 최대_사이즈; 유형 벡터 이 배열 (인덱스_타입 범위 << 고객명 >>님 의 요소_유형; 유형 스택 (Allocated_Size(할당 크기) :사이즈_타입 := 0) 이 기록. 정상 : 인덱스_타입; 보관소 : 벡터 (1 .. Allocated_Size(할당 크기)); 종료 레코드; 끝. 스택;
범용 패키지 인스턴스화:
type Bookmark_Type is new Natural; -- 편집 중인 텍스트 문서에 위치를 기록합니다. Bookmark_Stacks is new Stacks(최대 크기 => 20, Element_Type = > Bookmark_Type); -- 사용자가 문서의 기록된 위치 사이를 이동할 수 있습니다.
범용 패키지 인스턴스 사용:
유형 문서_유형 이 기록. 내용물 : 아다.줄들.무제한.무제한_문자열; 북마크 : 북마크_스택스.스택; 종료 레코드; 절차. 편집 (문서_이름 :에 스트링) 이 문서 : 문서_유형; 시작한다. -- 북마크 스택 초기화: 북마크_스택스.만들다 (S => 문서.북마크, Initial_Size(초기 사이즈) => 10); -- 이제 Document_Name 파일을 열고 읽습니다. 끝. 편집;
장점과 제한
언어 구문을 사용하면 일반적인 형식 매개 변수에 대한 제약 조건을 정확하게 지정할 수 있습니다.예를 들어, 일반적인 형식 유형은 모듈 형식만 실제 형식으로 받아들이도록 지정할 수 있습니다.일반적인 형식 매개 변수 간에 다음과 같은 제약 조건을 표현할 수도 있습니다.
포괄적인 유형 인덱스_타입 이 (<>); -- 이산형이어야 합니다. 유형 요소_유형 이 사적인; -- 제한되지 않는 임의의 타입을 사용할 수 있습니다. 유형 어레이_타입 이 배열 (인덱스_타입 범위 << 고객명 >>님 의 요소_유형;
이 예에서 Array_Type은 Index_Type과 Element_Type 모두에 의해 제약됩니다.장치를 인스턴스화할 때 프로그래머는 이러한 제약 조건을 충족하는 실제 배열 유형을 전달해야 합니다.
이 세분화된 제어의 단점은 복잡한 구문이지만, 모든 일반 형식 파라미터가 사양에 완전히 정의되어 있기 때문에 컴파일러는 일반의 본문을 보지 않고 일반을 인스턴스화할 수 있습니다.
C++와 달리 Ada는 특수한 범용 인스턴스를 허용하지 않으며 모든 제네릭을 명시적으로 인스턴스화해야 합니다.이러한 규칙에는 다음과 같은 몇 가지 결과가 있습니다.
- 컴파일러는 공유 제네릭스를 구현할 수 있습니다.일반 유닛의 오브젝트 코드를 모든 인스턴스 간에 공유할 수 있습니다(물론 프로그래머가 서브프로그램의 인라인화를 요구하지 않는 한).추가 결과:
- 모든 범용이 정확히 동일한 경우, 다른 사람이 작성한 프로그램을 검토하고 이해하는 것이 더 쉬우며, 고려할 "특별한 경우"가 없습니다.
- 모든 인스턴스화는 명확하지만 프로그램을 이해하기 어렵게 만드는 숨겨진 인스턴스화는 없습니다.
- Ada는 전문화를 허용하지 않기 때문에 "템플릿 메타프로그래밍"을 허용하지 않습니다.
C++ 템플릿
C++는 템플릿을 사용하여 범용 프로그래밍 기술을 활성화합니다.C++ 표준 라이브러리에는 공통 데이터 구조 및 알고리즘에 대한 템플릿 프레임워크를 제공하는 표준 템플릿 라이브러리(STL)가 포함되어 있습니다.C++의 템플릿은 템플릿 메타프로그래밍에도 사용할 수 있습니다.이는 실행 시간이 아닌 컴파일 시 코드의 일부를 사전 평가하는 방법입니다.템플릿 전문화를 사용하면 C++ 템플릿은 튜링 완료로 간주됩니다.
기술 개요
템플릿에는 여러 종류가 있으며 가장 일반적인 것은 함수 템플릿과 클래스 템플릿입니다.함수 템플릿은 인스턴스화 시 제공되는 파라미터화 타입에 따라 일반적인 함수를 작성하는 패턴이다.예를 들어 C++ 표준 템플릿 라이브러리에는 함수 템플릿이 포함되어 있습니다.max(x, y)
x 또는 y 중 큰 것을 반환하는 함수를 만듭니다. max()
는 다음과 같이 정의할 수 있습니다.
템플릿< >타이프네임 T> T 맥스.(T x, T y) { 돌아가다 x < > y ? y : x; }
이 함수 템플릿의 전문화, 특정 유형의 인스턴스화는 일반 함수처럼 호출할 수 있습니다.
표준::외치다 << > 맥스.(3, 7); // 출력 7
컴파일러는 호출에 사용되는 인수를 조사합니다.max
이 콜이 이 콜이라고 판단합니다.max(int, int)
그런 다음 매개 변수화 유형이 있는 함수의 버전을 인스턴스화합니다.T
이int
다음 기능에 상당합니다.
인트 맥스.(인트 x, 인트 y) { 돌아가다 x < > y ? y : x; }
이것은 인수가 다음 중 하나인지 아닌지에 관계없이 기능합니다.x
그리고.y
표현식의 정수, 문자열 또는 기타 유형입니다.x < y
합리적이고, 보다 구체적으로 말하면, 어떤 타입에 대해서도operator<
정의되어 있습니다.사용할 수 있는 타입 세트에는 공통 상속이 필요하지 않기 때문에 오리 타이핑과 매우 유사합니다.커스텀 데이터 타입을 정의하는 프로그램은 연산자 오버로드를 사용하여 의미를 정의할 수 있습니다.<
그 타입에 대해서, 따라서 그 타입을 사용할 수 있습니다.max()
함수 템플릿.이 분리된 예에서는 이것이 작은 이점처럼 보일 수 있지만, STL과 같은 포괄적인 라이브러리의 상황에서는 프로그래머가 새로운 데이터 유형에 대해 몇 개의 연산자를 정의하는 것만으로 광범위한 기능을 얻을 수 있습니다.정의만 내리면<
형식을 표준과 함께 사용할 수 있습니다.sort()
,stable_sort()
,그리고.binary_search()
알고리즘 또는 데이터 구조 내에 삽입할 수 있습니다.set
s, 힙 및 관련 배열.
C++ 템플릿은 컴파일 시 완전히 안전합니다.예를 들어 표준 타입은complex
는 정의되어 있지 않습니다.<
연산자, 왜냐하면 복소수에는 엄격한 순서가 없기 때문입니다.그러므로,max(x, y)
x 및 y가 다음과 같은 경우 컴파일 오류와 함께 실패합니다.complex
가치.마찬가지로 에 의존하는 다른 템플릿도<
적용할 수 없다complex
비교(함수 또는 함수의 형식)가 제공되지 않는 한 데이터.예: Acomplex
의 키로 사용할 수 없습니다.map
비교가 제공되지 않는 한.유감스럽게도 컴파일러는 이러한 종류의 오류에 대해 역사적으로 다소 난해하고 길고 도움이 되지 않는 오류 메시지를 생성합니다.특정 개체가 메서드 프로토콜을 준수하는지 확인하면 이 문제를 완화할 수 있습니다.사용하는 언어compare
대신<
사용할 수도 있다complex
값을 키로 지정합니다.
다른 종류의 템플릿인 클래스 템플릿은 같은 개념을 클래스로 확장합니다.클래스 템플릿 지정은 클래스입니다.클래스 템플릿은 일반 컨테이너를 만드는 데 자주 사용됩니다.예를 들어 STL에 연결된 목록 컨테이너가 있습니다.정수의 링크 리스트를 작성하려면 , 다음과 같이 씁니다.list<int>
. 문자열 목록이 표시됩니다.list<string>
.alist
에는 호환성이 있는 파라미터화 타입에 대해 동작하는 일련의 표준 함수가 관련되어 있습니다.
템플릿 전문화
C++ 템플릿의 강력한 기능은 템플릿 전문화입니다.이를 통해 인스턴스화되고 있는 파라미터화된 유형의 특정 특성을 기반으로 대체 구현을 제공할 수 있습니다.템플릿 특화에는 두 가지 목적이 있습니다.특정 형태의 최적화를 허용하는 것과 코드 블러트를 줄이는 것입니다.
예를 들어,sort()
템플릿 기능.이러한 기능이 수행하는 주요 활동 중 하나는 컨테이너 위치 중 두 곳의 값을 바꾸거나 교환하는 것입니다.값이 클 경우(각 값을 저장하는 데 필요한 바이트 수 측면에서), 먼저 오브젝트에 대한 개별 포인터 목록을 작성하고 포인터를 정렬한 다음 최종 정렬 시퀀스를 작성하는 것이 종종 더 빠릅니다.값이 매우 작을 경우에는 일반적으로 필요에 따라 값을 대신 교환하는 것이 가장 빠릅니다.또한 파라미터화된 타입이 이미 포인터 타입인 경우에는 별도의 포인터 배열을 구축할 필요가 없습니다.템플릿 전문화를 통해 템플릿 작성자는 다른 구현을 기술하고 사용하는 각 구현에 대해 매개 변수화된 유형이 가져야 하는 특성을 지정할 수 있습니다.
함수 템플릿과 달리 클래스 템플릿은 부분적으로 특수화할 수 있습니다.즉, 일부 템플릿파라미터가 알려진 경우 클래스 템플릿코드의 대체 버전을 제공하고 다른 템플릿파라미터는 범용으로 할 수 있습니다.예를 들어 파라미터화 타입의 복사가 비용이 많이 든다고 가정한 디폴트 실장(프라이머리 전문화)을 작성하고 복사 비용이 저렴한 타입의 부분 전문화를 작성함으로써 전체적인 효율을 높일 수 있습니다.이러한 클래스 템플릿의 클라이언트는 컴파일러가 각각의 케이스에서 프라이머리 전문화를 사용했는지 또는 일부 전문화를 사용했는지 알 필요 없이 그 전문화만 사용합니다.클래스 템플릿은 완전히 특수화할 수도 있습니다.즉, 모든 파라미터화 유형을 알고 있을 때 대체 구현을 제공할 수 있습니다.
장점과 단점
템플릿의 일부 사용 예:max()
함수(C 프로그래밍 언어의 유산)와 같은 전프로세싱ormacros로 채워졌습니다.예를 들어, 이러한 매크로의 가능한 실장은 다음과 같습니다.
#max(a, b) (a) < (b) ? (b) : (a)
매크로는 컴파일이 적절하기 전에 프리프로세서에 의해 확장(복사 붙여넣기)됩니다.템플릿은 실제 기능입니다.매크로는 항상 인라인으로 확장됩니다.템플릿은 컴파일러가 적절하다고 판단했을 때 인라인 함수일 수도 있습니다.
단, 템플릿은 일반적으로 이러한 목적으로 매크로보다 개선된 것으로 간주됩니다.템플릿은 타입 세이프입니다.템플릿을 사용하면 부작용이 있는 매개 변수를 두 번 평가하는 등 함수 매크로를 많이 사용하는 코드에서 발견되는 일반적인 오류를 방지할 수 있습니다.아마도 가장 중요한 것은 템플릿이 매크로보다 훨씬 더 큰 문제에 적용 가능하도록 설계되었다는 것입니다.
템플릿 사용에는 지원되는 기능, 컴파일러 지원, 불량 오류 메시지(보통 C++20 SFINAE 이전 버전) 및 코드 블로트라는 4가지 주요 단점이 있습니다.
- C++의 템플릿에는 많은 기능이 없기 때문에 구현과 직접적인 사용이 불가능할 수 있습니다.대신 프로그래머는 복잡한 트릭에 의존해야 합니다.그것은 비대해지고, 이해하기 어렵고, 코드를 유지하기 어렵게 됩니다.C++ 규격의 현재 개발에서는 이러한 트릭을 많이 사용하고 템플릿의 새로운 기능을 많이 구축하거나 이러한 트릭을 염두에 두고 있기 때문에 이 문제는 더욱 악화되고 있습니다.
- 많은 컴파일러는 역사적으로 템플릿에 대한 지원이 부족했기 때문에 템플릿을 사용하면 코드 이동성이 다소 떨어졌을 수 있습니다.C++ 컴파일러가 C++ 인식되지 않는 링커와 함께 사용되는 경우 또는 공유 라이브러리 경계를 넘어 템플릿을 사용하려고 하는 경우에도 지원이 저하될 수 있습니다.
- SFINAE를 [18]사용하는 코드에서 오류가 검출되면 컴파일러는 혼란스럽고 길고 때로는 도움이 되지 않는 오류 메시지를 생성할 수 있습니다.이로 인해 템플릿 개발이 어려워질 수 있습니다.
- 마지막으로 템플릿의 사용은 컴파일러가 템플릿 클래스 또는 함수의 개별 인스턴스를 생성해야 합니다.(이는 C++의 타입이 모두 같은 사이즈는 아니며 데이터 필드의 사이즈는 클래스가 동작하는 방법에 중요하기 때문입니다.)따라서 템플릿을 무분별하게 사용하면 코드가 대량으로 생성되어 실행 파일이 과도하게 커질 수 있습니다.단, 템플릿의 전문화 및 파생 기능을 적절히 사용하면 다음과 같은 경우에 이러한 코드 블러트를 극적으로 줄일 수 있습니다.
그러면 템플릿이 사용되기 때문에 코드 복제 문제를 줄이기 위해 파생 기능을 사용할 수 있을까요?여기에는 일반 수업에서 템플릿을 가져오는 것이 포함됩니다.이 기술은 실제 사용 시 코드 블러트를 억제하는 데 성공했습니다.이와 같은 기술을 사용하지 않는 사람들은 중간 크기의 프로그램에서도 복제된 코드가 메가바이트의 코드 공간을 차지할 수 있다는 것을 알게 되었습니다.
--
템플릿에 의해 생성되는 추가 인스턴스화로 인해 일부 디버거가 템플릿에서 정상적으로 동작하지 못할 수도 있습니다.예를 들어 소스 파일에서 템플릿 내의 디버깅 중단점을 설정하면 원하는 실제 인스턴스화의 중단점 설정을 놓치거나 템플릿이 인스턴스화되는 모든 위치에 중단점을 설정할 수 있습니다.
또, 템플릿의 실장 소스 코드는, 그것을 사용하는 번역 유닛(소스 파일)에 완전하게 사용할 수 있는 것(헤더에 포함)이 필요합니다.표준 라이브러리의 대부분을 포함한 템플릿은 헤더 파일에 포함되지 않은 경우 컴파일할 수 없습니다.(이는 비템플릿코드와는 대조적입니다.템플릿코드는 바이너리로 컴파일되어 이를 사용하는 코드에 대한 선언 헤더 파일만 제공합니다.)이는 일부 추상화를 제거하는 구현 코드를 노출함으로써 단점이 될 수 있으며 클로즈드 소스 [citation needed]프로젝트에서 사용이 제한될 수 있습니다.
D의 템플릿
D 프로그래밍 언어는 C++ 기반 설계에 기반한 템플릿을 지원합니다.대부분의 C++ 템플릿이 변경 없이 D로 넘어오지만 D는 다음과 같은 추가 기능을 추가합니다.
- D의 템플릿파라미터는 (C++20 이전 C++에서와 같이) 유형 및 원시값으로만 제한되지 않고 임의의 컴파일 시간 값(스트링 및 구조 리터럴 등) 및 다른 템플릿 또는 템플릿인스턴스화를 포함한 임의의 식별자에 대한 에일리어스도 허용합니다.
- 템플릿 제약 조건 및
static if
스테이트먼트는 각각 C++의 C++ 개념에 대한 대안을 제공합니다.if constexpr
. - 그
is(...)
expression을 사용하면 컴파일 시 오브젝트의 특성을 검증할 수 있습니다. - 그
auto
키워드 및typeof
expression은 변수 선언 및 함수 반환 값에 대한 유형 추론을 허용하며, 이는 다시 "Voldemort types"(글로벌 [20]이름이 없는 유형)를 허용합니다.
D의 템플릿은 C++와 다른 구문을 사용하는데 반해 C++의 템플릿 파라미터는 각 괄호로 둘러싸여 있습니다.Template<param1, param2>
), D는 느낌표와 괄호를 사용합니다.Template!(param1, param2)
이렇게 하면 비교 연산자와의 모호성으로 인한 C++ 구문 분석의 어려움을 피할 수 있습니다.파라미터가1개뿐일 경우 괄호는 생략할 수 있습니다.
일반적으로 D는 위의 특징을 결합하여 특성 기반의 범용 프로그래밍을 사용하여 컴파일 시간 다형성을 제공합니다.예를 들어, 입력 범위는 다음 항목에 의해 실행되는 체크를 충족하는 모든 유형으로 정의됩니다.isInputRange
의 정의는 다음과 같습니다.
템플릿 isInputRange(R) { 열거하다 부울 isInputRange = 이(유형( (인아웃 인트 = 0) { R r = R.초기화; // 범위 개체를 정의할 수 있습니다. 한다면 (r.빈) {} // 비어 있는지 테스트할 수 있습니다. r.팝프런트(); // popFront()를 호출할 수 있습니다. 자동 h = r.전선.; // 범위의 앞부분을 가져올 수 있습니다. })); }
입력 범위만 받아들이는 함수는 템플릿 제약조건에서 위의 템플릿을 사용할 수 있습니다.
자동 재밌어요(범위)(범위 범위) 한다면 (isInputRange!범위) { // ... }
코드 생성
템플릿 메타프로그래밍과 더불어 D는 컴파일 타임코드 생성을 가능하게 하는 몇 가지 기능도 제공합니다.
- 그
import
expression을 사용하면 디스크에서 파일을 읽고 그 내용을 문자열 표현식으로 사용할 수 있습니다. - 컴파일 시간 리플렉션을 사용하면 컴파일 중에 선언과 그 멤버를 열거하고 검사할 수 있습니다.
- 사용자 정의 속성을 사용하면 선언에 임의의 식별자를 부가할 수 있으며 선언은 컴파일 시간 리플렉션을 사용하여 열거할 수 있습니다.
- Compile-Time Function Execution(CTFE; 컴파일 시간 함수 실행)을 사용하면 컴파일 중에 D의 서브셋(안전한 동작으로 제한됨)을 해석할 수 있습니다.
- 문자열 믹스인을 사용하면 프로그램의 일부가 되는 D 코드로 문자열 식의 내용을 평가하고 컴파일할 수 있습니다.
상기의 조합에 의해, 기존의 선언에 근거해 코드를 생성할 수 있습니다.예를 들어, D 시리얼라이제이션 프레임워크는 타입의 멤버를 열거하고 시리얼라이제이션 및 시리얼라이제이션 해제를 수행하기 위해 시리얼라이제이션된 타입별로 특수한 함수를 생성할 수 있습니다.유저 정의 어트리뷰트는, 시리얼라이제이션 규칙을 한층 더 나타낼 가능성이 있습니다.
그import
expression 및 컴파일 타임 함수 실행은 도메인 고유의 언어를 효율적으로 구현할 수도 있습니다.예를 들어 HTML 템플릿이 포함된 문자열을 사용하여 동등한 D 소스 코드를 반환하는 함수를 지정하면 다음과 같은 방법으로 사용할 수 있습니다.
// 문자열 매니페스트 상수로 example.htt의 내용을 Import합니다. 열거하다 html Template = 수입품("190.disples"); // HTML 템플릿을 D 코드로 변환합니다. 열거하다 html DCode = htmlTemplateToD(html Template); // htmlDCode의 내용을 D코드로 붙여넣습니다. 혼재(html DCode);
에펠의 보편성
일반 수업은 원래 방법과 언어 디자인부터 에펠의 일부였습니다.에펠의 [21][22]기초 간행물에서는 범용 클래스의 생성과 사용을 설명하기 위해 일반성이라는 용어를 사용합니다.
기본/무제한 범용성
일반 클래스는 클래스 이름과 하나 이상의 공식 일반 매개 변수 목록을 사용하여 선언됩니다.다음 코드에서 class는LIST
에는 1개의 정식 범용 파라미터가 있습니다.G
학급 목록. [G] ... 특징 -- 액세스 아이템: G -- 현재 커서가 가리키는 항목 ... 특징 -- 요소 변경 놓다 (new_아이템: G) -- 목록 끝에 'new_item'을 추가합니다. ...
정식 범용 파라미터는 임의의 클래스 이름의 플레이스 홀더로, 아래 2개의 범용 파생상품에 나타나듯이 범용 클래스를 선언할 때 제공됩니다.ACCOUNT
그리고.DEPOSIT
다른 클래스 이름입니다. ACCOUNT
그리고.DEPOSIT
대체하기 위한 실제 클래스 이름을 제공하기 때문에 실제 범용 파라미터로 간주됩니다.G
실제 사용 중입니다.
목록_of_interface: 목록. [계좌] -- 계정 목록 목록_of_interface: 목록. [보증금] -- 예금 리스트
에펠식 시스템 내에서는 수업이지만LIST [G]
클래스로 간주되며 유형으로 간주되지 않습니다.단, 의 일반적인 파생은LIST [G]
예를 들어LIST [ACCOUNT]
유형으로 간주됩니다.
제약된 일반성
상기의 리스트클래스의 경우, 실제 범용 파라미터는 다음을 대체하고 있습니다.G
사용 가능한 다른 클래스가 될 수 있습니다.유효한 실제 범용 파라미터를 선택할 수 있는 클래스 세트를 제한하기 위해 범용 제약조건을 지정할 수 있습니다.계급선언서SORTED_LIST
아래 일반 제약조건은 유효한 실제 일반 파라미터가 클래스에서 상속되는 클래스가 되도록 지시합니다.COMPARABLE
. 일반적인 제약조건에 의해 다음 요소가SORTED_LIST
실제로 분류할 수 있습니다.
학급 정렬됨_리스트 [G -> 비교LE]
Java에서의 범용 기능
J2SE 5.0의 일부로 2004년에 Java 프로그래밍 언어에 제네릭 또는 "containers-of-type-T" 지원이 추가되었습니다.Java 에서는 제네릭이 컴파일시에만 타입의 정확성을 체크합니다.범용 유형 정보는 이전 JVM 구현과의 호환성을 유지하기 위해 유형 삭제라는 프로세스를 통해 제거되며 런타임에 사용할 수 없습니다.예를 들어,List<String>
raw 타입으로 변환됩니다.List
컴파일러는 타입캐스트를 삽입하여 요소를 변환합니다.String
를 입력하면 C++ 템플릿 등의 다른 구현에 비해 성능이 저하됩니다.
의 범용성.NET [C#, VB]네트워크]
제네릭이 의 일부로 추가되었습니다.NET Framework 2.0은 Microsoft Research가 [23]1999년에 시작한 리서치 프로토타입을 기반으로 2005년 11월에 시작되었습니다.Java의 제네릭과 비슷하지만,NET 제네릭스는 유형 삭제를 적용하지 않지만 복제를 사용하여 런타임에 퍼스트 클래스 메커니즘으로 제네릭스를 구현합니다.이 설계에서는 범용 타입의 보존에 의한 반영을 가능하게 하는 것 외에 범용 [24][25]어레이를 작성할 수 없는 것 등 소거에 관한 제한의 일부를 경감하는 등 추가 기능을 제공합니다.이는 런타임 캐스트와 일반적으로 값비싼 복싱 변환으로 인한 성능 저하가 없음을 의미합니다.primitive 및 value type을 범용 인수로 사용하면 특수한 구현을 통해 효율적인 범용 수집 및 메서드를 구현할 수 있습니다.C++ 및 Java와 마찬가지로 Dictionary <string, List <int> 등의 네스트된 범용 타입은 유효한 타입이지만 코드 분석 설계 [26]규칙 내의 멤버시그니처에는 사용하지 않는 것이 좋습니다.
.NET 에서는, 6 종류의 범용 타입의 제약이 허가되고 있습니다.where
범용 타입을 값 타입, 클래스, 컨스트럭터 및 인터페이스 [27]구현으로 제한하는 키워드입니다.다음으로 인터페이스 제약의 예를 나타냅니다.
사용. 시스템.; 학급 샘플 { 정적인 무효 주된() { 인트[] 배열 = { 0, 1, 2, 3 }; 최소 제작< >인트>(배열, 2); // 어레이를 {2, 2, 3}(으)로 변경 앞지르다 (인트 i 에 배열) 콘솔.기입선(i); // 결과를 인쇄합니다. 콘솔.읽기 키(진실의); } 정적인 무효 최소 제작< >T>(T[] 목록., T 최저의) 어디에 T : 비교할 수 없다< >T> { 위해서 (인트 i = 0; i < > 목록..길이; i++) 한다면 (목록.[i].비교 대상(최저의) < > 0) 목록.[i] = 최저의; } }
그MakeAtLeast()
method는 일반적인 유형의 요소를 사용하여 어레이에서 작업을 수행할 수 있습니다.T
. 메서드의 유형 제약조건은 메서드가 모든 유형에 적용됨을 나타냅니다.T
일반적인 기능을 구현합니다.IComparable<T>
인터페이스입니다.이렇게 하면 해당 유형이 비교를 지원하지 않는 경우 메서드가 호출될 경우 컴파일 시간 오류가 발생합니다.인터페이스는 일반적인 메서드를 제공합니다.CompareTo(T)
.
위의 방법은 일반적이지 않은 형식을 사용하여 일반 유형 없이 작성할 수도 있습니다.Array
type. 단, 배열이 서로 어긋나기 때문에 캐스팅이 안전하지 않고 컴파일러가 범용 타입을 사용할 때 발생할 수 있는 특정 오류를 찾을 수 없습니다.또한 이 메서드는 다음과 같이 어레이 항목에 액세스해야 합니다.object
대신 두 요소를 비교하기 위해 캐스팅이 필요합니다.(다음과 같은 값 유형의 경우)int
이것은 복싱 변환이 필요하지만, 이것은 복싱 변환을 사용하여 해결할 수 있습니다.Comparer<T>
클래스(표준 컬렉션 클래스에서 수행됨)
범용 스태틱멤버의 주목할 만한 동작NET 클래스는 런타임타입별 스태틱멤버 인스턴스화입니다(아래 예 참조).
//일반 클래스 일반의 학급 제너레이션 테스트< >T> { //정적 변수 - 반사 시 각 유형에 대해 생성됩니다. 정적인 카운트된 인스턴스 OnePerType(원퍼타입) = 신규 카운트된 인스턴스(); //데이터 멤버 사적인 T mT; //생성자 생성자 일반의 제너레이션 테스트(T pT) { mT = pT; } } //a 클래스 일반의 학급 카운트된 인스턴스 { // 정적 변수 - 인스턴스당 한 번씩 증가합니다. 일반의 정적인 인트 계산대; //생성자 생성자 일반의 카운트된 인스턴스() { //개체 인스턴스화 중 카운터를 1개씩 표시 카운트된 인스턴스.계산대++; } } //주 코드 진입점 //실행 종료 시 카운트됨인스턴스카운터 = 2 제너레이션 테스트< >인트> g1 = 신규 제너레이션 테스트< >인트>(1); 제너레이션 테스트< >인트> g11 = 신규 제너레이션 테스트< >인트>(11); 제너레이션 테스트< >인트> ᄀ = 신규 제너레이션 테스트< >인트>(111); 제너레이션 테스트< >이중으로 하다> g2 = 신규 제너레이션 테스트< >이중으로 하다>(1.0);
델파이의 일반성
델파이의 오브젝트 파스칼 사투리는 델파이의 2007년 릴리즈에서 제네릭스를 획득했습니다.처음에는 (현재 단종된)에서만 사용되었습니다.NET 컴파일러가 Dellphi 2009 릴리즈에서 네이티브 코드에 추가되기 전.Delphi 제네릭스의 의미와 기능은 주로 에서 제네릭스가 가진 의미와 기능을 모델로 하고 있습니다.NET 2.0. 단, 실장은 필연적으로 상당히 다릅니다.위의 첫 번째 C#의 예를 다소 직접 번역해 보겠습니다.
프로그램. 샘플; {$APPTYPE CONSOLE} 사용하다 범용.디폴트; //IComparer의 경우 </> 유형 TUTils = 학급 학급 절차. 최소 제작< >T>(아아: TAray< >T>; 컨스턴트 최하위: T; 비교자: ICMPARER< >T>); 과부하; 학급 절차. 최소 제작< >T>(아아: TAray< >T>; 컨스턴트 최하위: T); 과부하; 끝.; 학급 절차. TUTils.최소 제작< >T>(아아: TAray< >T>; 컨스턴트 최하위: T; 비교자: ICMPARER< >T>); 변화하다 I: 정수; 시작한다. 한다면 비교자 = 제로 그리고나서 비교자 := TComparer< >T> 。체납; 위해서 I := 낮다(아아) 로. 높은(아아) 하다 한다면 비교자.비교하다(아아[I], 최하위) < > 0 그리고나서 아아[I] := 최하위; 끝.; 학급 절차. TUTils.최소 제작< >T>(아아: TAray< >T>; 컨스턴트 최하위: T); 시작한다. 최소 제작< >T>(아아, 최하위, 제로); 끝.; 변화하다 인츠: TAray< >정수>; 가치: 정수; 시작한다. 인츠 := TAray< >정수> 。만들다(0, 1, 2, 3); TUTils.최소 제작< >정수>(인츠, 2); 위해서 가치 에 인츠 하다 기입(가치); 읽기; 끝..
C#과 마찬가지로 메서드 및 전체 유형에는 하나 이상의 유형 파라미터를 지정할 수 있습니다.이 예에서 TArray는 일반 유형(언어로 정의됨)이고 MakeAtLest는 일반 메서드입니다.사용 가능한 제약조건은 C#에서 사용 가능한 제약조건과 매우 유사합니다.즉, 임의의 값 유형, 임의의 클래스, 특정 클래스 또는 인터페이스, 파라미터가 없는 컨스트럭터가 있는 클래스입니다.여러 제약조건이 가법 결합으로 작용합니다.
Free Pascal의 범용성
프리 파스칼은 델파이 이전에 제네릭스를 구현했으며 구문과 의미론도 다양했습니다.단, FPC 버전 2.6.0 이후로는 {$mode Delphi} 언어 모드를 사용할 때 Delphi 스타일의 구문을 사용할 수 있습니다.따라서 Free Pascal 프로그래머는 자신이 원하는 스타일로 제네릭스를 사용할 수 있습니다.
Dellphi 및 Free Pascal의 예:
// 델파이 스타일 구성 단위 A; {$ifdef fpc} {$mode delphi} {$endif} 인터페이스 유형 TGeneric 클래스< >T> = 학급 기능. 푸우(컨스턴트 에바루: T): T; 끝.; 실행 기능. TGeneric 클래스< >T> 。푸우(컨스턴트 에바루: T): T; 시작한다. 결과 := 에바루 + 에바루; 끝.; 끝.. // 프리 파스칼의 ObjFPC 스타일 구성 단위 B; {$ifdef fpc} {$mode objfpc} {$endif} 인터페이스 유형 포괄적인 TGeneric 클래스< >T> = 학급 기능. 푸우(컨스턴트 에바루: T): T; 끝.; 실행 기능. TGeneric 클래스.푸우(컨스턴트 에바루: T): T; 시작한다. 결과 := 에바루 + 에바루; 끝.; 끝.. // 사용 예, 델파이 스타일 프로그램. 테스트 Gen Delphi; {$ifdef fpc} {$mode delphi} {$endif} 사용하다 A,B; 변화하다 GC1: A.TGeneric 클래스< >정수>; GC2: B.TGeneric 클래스< >스트링>; 시작한다. GC1 := A.TGeneric 클래스< >정수> 。만들다; GC2 := B.TGeneric 클래스< >스트링> 。만들다; 기입(GC1.푸우(100)); // 200 기입(GC2.푸우('안녕하세요')); // 헬로 GC1.공짜; GC2.공짜; 끝.. // 사용 예, ObjFPC 스타일 프로그램. 테스트 Gen Delphi; {$ifdef fpc} {$mode objfpc} {$endif} 사용하다 A,B; // ObjFPC에서는 필수 유형 TAGeneric 클래스내부 = 전문화하다 A.TGeneric 클래스< >정수>; TBGeneric ClassString = 전문화하다 B.TGeneric 클래스< >스트링>; 변화하다 GC1: TAGeneric 클래스내부; GC2: TBGeneric ClassString; 시작한다. GC1 := TAGeneric 클래스내부.만들다; GC2 := TBGeneric ClassString.만들다; 기입(GC1.푸우(100)); // 200 기입(GC2.푸우('안녕하세요')); // 헬로 GC1.공짜; GC2.공짜; 끝..
기능 언어
해스켈의 일반성
Haskell의 유형 클래스 메커니즘은 일반 프로그래밍을 지원합니다.Haskell에서 사전 정의된 유형 클래스 중 6개(포함)Eq
, 동등성을 위해 비교할 수 있는 유형 및Show
값을 문자열로 렌더링할 수 있는 유형)에는 파생 인스턴스를 지원하는 특별한 속성이 있습니다.즉, 새로운 유형을 정의하는 프로그래머는 클래스 인스턴스를 선언할 때 일반적으로 필요한 클래스 메서드의 구현을 제공하지 않고 이 유형이 이러한 특수 유형 클래스의 인스턴스임을 나타낼 수 있습니다.필요한 모든 방법은 유형 구조에 따라 자동으로 구축되는 "파생성됩니다.예를 들어, 다음 바이너리 트리 유형의 선언은 클래스 인스턴스가 되는 것을 나타냅니다.Eq
그리고.Show
:
데이터. 빈 트리 a = 잎 a 노드 (빈 트리 a) a (빈 트리 a) 유도하다 (이크, 표시)
그 결과 등식함수(==
및 문자열 표현 함수(show
)는 폼의 모든 유형에 대해 자동으로 정의됩니다.BinTree T
이라면T
그 자체가 이러한 조작을 서포트하고 있습니다.
파생 인스턴스 지원Eq
그리고.Show
그들의 방법을 만든다.==
그리고.show
파라메트릭 다형함수와 질적으로 다른 방법으로 일반: 이러한 "다형함수"(더 정확하게는 유형별 함수 패밀리)는 다양한 유형의 값에 적용될 수 있으며 인수 유형에 따라 다르게 동작하지만 새로운 유형에 대한 지원을 추가하기 위해 거의 작업이 필요하지 않습니다.Ralf Hinze(2004)는 특정 프로그래밍 기법에 의해 사용자 정의 유형 클래스에서도 유사한 효과를 얻을 수 있음을 보여주었다.다른 연구자들은 Haskell과 Haskell의 맥락에서 이것과 다른 종류의 일반성에 대한 접근방식을 제안했습니다(아래에서 논의).
폴리P
PolyP는 Haskell에 대한 최초의 범용 프로그래밍 언어 확장입니다.PolyP에서는 범용 기능을 Polytypic이라고 부릅니다.이 언어는 정규 데이터형의 패턴 펑터의 구조에 걸쳐 구조 유도를 통해 그러한 다형 함수를 정의할 수 있는 특별한 구조를 도입한다.PolyP의 일반 데이터 유형은 Haskell 데이터 유형의 하위 집합입니다.정규 데이터형 t는 종류 * → *이어야 하며, a가 정의의 형식 형식 인수인 경우 t에 대한 모든 재귀 호출은 t a 형식이어야 합니다.이러한 제한에 의해, 상위 종류의 데이터 타입이나, 재귀 콜의 형식이 다른 네스트 데이터 타입은 제외됩니다.PolyP의 평탄함수는 다음과 같습니다.
평평하게 하다 :: 규칙적인. d => d a -> [a] 평평하게 하다 = 카타 움직이다 다중 타입의 움직이다 :: f a [a] -> [a] 사례. f 의 g+h -> 어느 하나 움직이다 움직이다 g*h -> \(x,y) -> 움직이다 x ++ 움직이다 y () -> \x -> [] 파 -> \x -> [x] 인식 -> \x -> x d@g -> 콘센트 . 평평하게 하다 . pmap 움직이다 단점 t -> \x -> [] 카타 :: 규칙적인. d => (기능자 d a b -> b) -> d a -> b
범용 해스켈
Generic Haskell은 네덜란드 위트레흐트 대학에서 개발된 Haskell의 또 다른 확장판입니다.제공되는 확장 기능은 다음과 같습니다.
- 유형 색인화된 값은 다양한 Haskell 유형 생성자(단위, 원시 유형, 합계, 곱 및 사용자 정의 유형 생성자)에서 색인화된 값으로 정의됩니다.또한 컨스트럭터 케이스를 사용하여 특정 컨스트럭터에 대한 유형 인덱스 값의 동작을 지정하고 디폴트 케이스를 사용하여 다른 일반적인 정의를 재사용할 수도 있습니다.
생성된 유형 인덱스 값은 모든 유형에 고유할 수 있습니다.
- 종류 색인화된 유형은 종류에 따라 색인화된 유형으로 *와 k → k' 모두에 대해 대소문자를 지정하여 정의됩니다.인스턴스는 kind-indexed 유형을 kind에 적용하여 가져옵니다.
- 일반 정의는 유형 또는 종류에 적용하여 사용할 수 있습니다.이것을 범용 어플리케이션이라고 부릅니다.결과는 적용되는 일반 정의의 종류에 따라 유형 또는 값입니다.
- 범용 추상화를 사용하면 (특정 종류의) 유형 매개 변수를 추상화하여 범용 정의를 정의할 수 있습니다.
- 유형 색인화 유형은 유형 생성자를 통해 인덱싱되는 유형입니다.이것들은, 보다 관련성이 높은 범용치에 타입을 지정하는 경우에 사용할 수 있습니다.생성된 유형 색인화 유형은 모든 유형에 고유할 수 있습니다.
예를 들어, Generic Haskell의 [28]등식 함수는 다음과 같습니다.
유형 이크 {[ * ]} t1 t2 = t1 -> t2 -> 불 유형 이크 {[ k -> l ]} t1 t2 = 전면적으로 u1 u2. 이크 {[ k ]} u1 u2 -> 이크 {[ l ]} (t1 u1) (t2 u2) 이큐 { t :: k } :: 이크 {[ k ]} t t 이큐 { 구성 단위 } _ _ = 진실의 이큐 { :+: } eqA eqB (인루 a1) (인루 a2) = eqA a1 a2 이큐 { :+: } eqA eqB (입력 b1) (입력 b2) = eqB b1 b2 이큐 { :+: } eqA eqB _ _ = 거짓의 이큐 { :*: } eqA eqB (a1 :*: b1) (a2 :*: b2) = eqA a1 a2 & & eqB b1 b2 이큐 { 내부 } = (==) 이큐 { 문자 } = (==) 이큐 { 불 } = (==)
깨끗한
Clean은 GHC에서 지원되는 범용 프로그래밍 기반 PolyP 및 범용 해스켈을 제공합니다.© 6.0 。종류별로 매개변수를 지정하지만 과부하를 제공합니다.
기타 언어
ML 패밀리의 언어들은 파라메트릭 다형성과 펑터라고 불리는 범용 모듈을 통한 범용 프로그래밍을 지원합니다.Standard ML과 OCaml 모두 클래스 템플릿 및 Ada의 범용 패키지와 유사한 펑터를 제공합니다.스킴 구문 추상화는 일반성과도 관련이 있습니다.실제로 C++ 템플릿의 슈퍼셋입니다.
Verilog 모듈은 1개 이상의 파라미터를 취득할 수 있습니다.이 파라미터에는 모듈의 인스턴스화 시 실제 값이 할당됩니다.예를 들어 일반적인 레지스터 배열은 배열 너비가 매개 변수를 통해 지정됩니다.이러한 어레이를 범용 와이어 벡터와 조합하면 단일 모듈 [29]구현에서 임의의 비트 폭을 가진 범용 버퍼 또는 메모리 모듈을 만들 수 있습니다.
Ada에서 파생된 VHDL에는 일반 기능도 있습니다.[30]
C는 다음 명령어를 사용하여 "type-generic 식"을 지원합니다._Generic
키워드:[31]
#define cbrt(x) _Generic((x), long double: cbrtl, \ 디폴트: cbrt, \ 플로트: cbrtf)(x)
「 」를 참조해 주세요.
레퍼런스
- ^ Lee, Kent D. (15 December 2008). Programming Languages: An Active Learning Approach. Springer Science & Business Media. pp. 9–10. ISBN 978-0-387-79422-8.
- ^ Milner, R.; Morris, L.; Newey, M. (1975). "A Logic for Computable Functions with Reflexive and Polymorphic Types". Proceedings of the Conference on Proving and Improving Programs.
- ^ Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John (1994). Design Patterns. Addison-Wesley. ISBN 0-201-63361-2.
- ^ Musser & Stephanov 1989.
- ^ Musser, David R.; Stepanov, Alexander A. Generic Programming (PDF).
- ^ Alexander Stepanov; Paul McJones (19 June 2009). Elements of Programming. Addison-Wesley Professional. ISBN 978-0-321-63537-2.
- ^ Musser, David R.; Stepanov, Alexander A. (1987). "A library of generic algorithms in Ada". Proceedings of the 1987 Annual ACM SIGAda International Conference on Ada: 216–225. CiteSeerX 10.1.1.588.7431. doi:10.1145/317500.317529. ISBN 0897912438. S2CID 795406.
- ^ Alexander Stephanov 및 Meng Lee:표준 템플릿 라이브러리.HP Laboraties 테크니컬 리포트 95-11(R.1), 1995년 11월 14일
- ^ Matthew H. Austern: 범용 프로그래밍 및 STL: C++ 표준 템플릿 라이브러리 사용 및 확장.애디슨 웨슬리 롱맨 출판사미국, 매사추세츠, 보스턴, 1998년
- ^ 제레미 G.Sik, Lie-Quan Lee, Andrew Lumsdaine:부스트 그래프 라이브러리:사용자 가이드 및 참조 매뉴얼.애디슨-웨슬리 2001
- ^ Stepanov, Alexander. Short History of STL (PDF).
- ^ a b Stroustrup, Bjarne. Evolving a language in and for the real world: C++ 1991-2006 (PDF). doi:10.1145/1238844.1238848. S2CID 7518369.
- ^ Lo Russo, Graziano. "An Interview with A. Stepanov".
- ^ Roland Backhouse; Patrik Jansson; Johan Jeuring; Lambert Meertens (1999). Generic Programming – an Introduction (PDF).
- ^ Lämmel, Ralf; Peyton Jones, Simon. "Scrap Your Boilerplate: A Practical Design Pattern for Generic Programming" (PDF). Microsoft. Retrieved 16 October 2016.
- ^ Gabriel Dos Reis; Jaakko Ja ̈rvi (2005). "What is Generic Programming? (preprint LCSD'05)" (PDF). Archived from the original (PDF) on 25 December 2005.
- ^ R. Garcia; J. Ja ̈rvi; A. Lumsdaine; J. Siek; J. Willcock (2005). "An extended comparative study of language support for generic programming (preprint)". CiteSeerX 10.1.1.110.122.
{{cite journal}}
:Cite 저널 요구 사항journal=
(도움말) - ^ Strustrup, Dos Reis (2003) :개념 - 템플릿 인수 확인을 위한 설계 선택 항목
- ^ Stroustrup, Bjarne (1994). "15.5 Avoiding Code Replication". The Design and Evolution of C++. Reading, Massachusetts: Addison-Wesley. pp. 346–348. Bibcode:1994dec..book.....S. ISBN 978-81-317-1608-3.
- ^ Bright, Walter. "Voldemort Types in D". Dr. Dobbs. Retrieved 3 June 2015.
- ^ 오브젝트 지향 소프트웨어 구축, 프렌티스 홀, 1988 및 프렌티스 홀, 제2판 오브젝트 지향 소프트웨어 구축, 1997.
- ^ 에펠: 언어, 프렌티스 홀, 1991년.
- ^ .NET/C# Generics 이력: 1999년 2월 사진 일부
- ^ C#: 어제, 오늘, 내일:앤더스 헤일스버그 인터뷰
- ^ C#, Java 및 C++ 범용
- ^ Code Analysis CA1006: 멤버 시그니처에 범용 타입을 네스트하지 않음
- ^ 유형 파라미터의 제약사항(C# 프로그래밍 가이드)
- ^ 일반적인 Haskell 사용자 가이드
- ^ 나머지 섹션 참조를 위해 예제를 사용하여 로그를 확인합니다.블레인 CReadler, Full Arc Press, 2011.ISBN 978-0-9834973-0-1
- ^ https://www.ics.uci.edu/~jmoorkan/generics.vHDL 레퍼런스
- ^ WG14 N1516 위원회 초안 - 2010년 10월 4일
원천
- Musser, D. R.; Stepanov, A. A. (1989). "Generic programming". In P. Gianni (ed.). Symbolic and Algebraic Computation: International symposium ISSAC 1988. Lecture Notes in Computer Science. Vol. 358. pp. 13–25. doi:10.1007/3-540-51084-2_2. ISBN 978-3-540-51084-0.
- Stroustrup, Bjarne (2007). Evolving a language in and for the real world: C++ 1991-2006 (PDF). ACM HOPL 2007.
- Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. Bibcode:1995dper.book.....G. ISBN 0-201-63361-2.
추가 정보
- Gabriel Dos Reis와 Jaakko Jérvi, Generic Programming이란?, LCSD 2005, Wayback Machine에서 2019년 8월 28일 아카이브 완료.
- Gibbons, Jeremy (2007). Backhouse, R.; Gibbons, J.; Hinze, R.; Jeuring, J. (eds.). Datatype-generic programming. Spring School on Datatype-Generic Programming 2006. Lecture Notes in Computer Science. Vol. 4719. Heidelberg: Springer. pp. 1–71. CiteSeerX 10.1.1.159.1228.
- Meyer, Bertrand (1986). "Genericity versus inheritance". Conference proceedings on Object-oriented programming systems, languages and applications - OOPSLA '86. pp. 391–405. doi:10.1145/28697.28738. ISBN 0897912047. S2CID 285030.
외부 링크
- generic-programming.org
- 알렉산더 A.스테파노프, 알렉산더 A의 논문 수집가. Stepanov(STL 작성자)
- C++/D
- 월터 브라이트, 템플릿 재방문
- David Vandevoorde, Nicolai M Josuttis, C++ 템플릿: 컴플리트 가이드, 2003년 애디슨 웨슬리ISBN 0-201-73484-2
- C#/.NET
- Jason Clark, "Introducting Generics in the Microsoft CLR", 2003년 9월, MSDN Magazine, Microsoft.
- Jason Clark, "Microsoft CLR의 제네릭스에 대한 자세한 내용", 2003년 10월, MSDN Magazine, Microsoft.
- 제너릭스의 아미르 마니아 씨넷. C#용 오픈소스 제네릭스 라이브러리입니다.
- 델파이/오브젝트 파스칼
- Nick Hodges, "Delphi 2009 Reviewers Guide", 2008년 10월 엠바카데로 개발자 네트워크, 엠바카데로
- 크레이그 스턴츠, "Delphi 2009 Generics and Type Constraints", 2008년 10월
- Dr. Bob, "Delphi 2009 Generics"
- 프리 파스칼:무료 Pascal 레퍼런스 가이드 제8장: Generics, Michael Van Canneyt,
- Delphi for Win32: Generics with Delphi 2009 Win32, Sébastien DOERENE, 2008
- 델파이 for.NET: Delphi Generics, Felix COLIBRI, 2008
- 에펠
- 하스켈
- 요한 주링, 숀 레더, 호세 페드로 마갈하이스, 알렉세이 로드리게스 야쿠셰프.해스켈의 범용 프로그래밍 라이브러리.위트레흐트 대학교
- Dév Clarke, Johan Jeuring 및 Andres Löh, Haskell 범용 사용자 가이드
- 2004년 ACM SIGPLAN International Conference on Functional Programming (ICFP; 기능 프로그래밍에 관한 국제회의) 속행에서 "대중을 위한 제네릭스", Ralf Hinze.
- Simon Peyton Jones, 편집자, The Haskell 98 Language Report, 개정판 2002.
- Ralf Lémmel과 Simon Peyton Jones, "보일러플레이트를 스크랩: 범용 프로그래밍을 위한 실용적인 디자인 패턴", ACM SIGPLAN 국제 언어 설계 및 구현 유형에 관한 워크숍(TLDI'03), 2003년 (이 웹사이트도 참조).
- Andres Löh, 범용 해스켈의 탐구, 박사 논문, 2004년 위트레흐트 대학교.ISBN 90-393-3765-9
- Generic Haskell: 범용 프로그래밍
- 자바
- Gilad Bracha, Java Programming Language Generics, 2004.
- Maurice Naftalin and Philip Wadler, Java Generics and Collections, 2006, O'Reilly Media, Inc.ISBN 0-596-52775-6
- Peter Sestoft, Java Precision, Second Edition, 2005년 MIT Press.ISBN 0-262-69325-9
- Java에서의 범용 프로그래밍, 2004년 Sun Microsystems, Inc.
- Angelika Langer, Java Generics FAQ