Concepts : Generic Programming의 미래
모든 내용은 Bjarne Stroustrup 교수님의 Good_Concepts에서 발췌하였습니다.
Concepts 의 사용은 기존의 Unconstrained Template ( 제한되지 않은, 제약 없는 ) 에 비해 Runtime 비용이 없음을 의미합니다.
순전히 선택 메커니즘이며 선택 후 생성된 코드는 기존 템플릿 코드와 동일합니다.
1. 약간의 배경 지식
1987년경 Bjarne Stroustrup 교수는 적절한 인터페이스로 템플릿을 디자인하려고 했으나 실패했습니다.
원한 속성은 다음과 같습니다.
-
완전한 일반성 / 표현성
-
수작업 코딩에 비해 오버 헤드가 없음
-
잘 지정된 (well-specified) 인터페이스
그러나, 아무도 어떻게 이 세 속성을 다 얻을 수 있는지 알 수 없었습니다. 대신 다음과 같은 세 속성을 얻었습니다.
-
튜링 완성도
-
수작업 코딩보다 우수한 성능
-
형편없는 인터페이스 ( 기본적으로 컴파일 타임에 덕 타이핑 )
잘 지정된 (well-specified) 인터페이스가 없기 때문에, 템플릿은 매우 더러운 오류 메세지가 나타납니다.
인터페이스의 부족은 수많은 사람을 수년간 괴롭혔습니다. 템플릿이 C++[Str94]의 기본 설계 기준을 충족하지 못했기 때문입니다.
오늘날, 템플릿에 대한 목표는 일반적인 C++ 디자인 목표와 같습니다.
인터페이스 사양 문제에 대한 해결책은 Alex Stepanov가 'Concepts' (개념) 라고 명명했습니다.
Concepts는 템플릿 인수 집합에 대한 일련의 요구사항 입니다.
2. 일반적인 프로그래밍 (Generic Programming)
C++에서 Generic Programming을 단순화할 필요가 있습니다.
Generic Code를 작성하는 방법은 다른 코드를 작성하는 방식과는 너무 다릅니다.
// Traditional Code
double sqrt(double d); // C++84 : double 인 모든 d를 허용
double d = 7;
double d2 = sqrt(d); // well, d는 double 입니다.
vector<string> vs = {"Good", "Old", "Templates"};
double d3 = sqrt(vs); // Ill-formed, vs는 double이 아닙니다.
이것은 프로그래밍을 배우는 첫날 쯤에 알게되는 종류의 코드입니다. double을 요구하도록 지정된 함수 sqrt가 있습니다.
만약 double이 아닌 타입을 넘기면 ( sqrt(vs) 와 같이 )
즉시 'vector<string>은 double이 아닙니다' 라는 오류메세지를 받게 됩니다.
이와는 다르게
// 1990s의 일반적인 코드 스타일
template <class T> void sort(T& c) // C++98 : c는 모든 유형 T 가능
{
// T의 속성에 따라서 정렬을 위한 코드가 들어있습니다.
// 예를들어 operator[] 와 operator<가 있는 유형이 오길 기대합니다.
}
vector<string> vs = {"Good", "Old", "Templates"};
sort(vs); // Well, vs가 정렬에 필요한 모든 속성을 갖습니다.
double d = 7;
sort(d); //Ill-formed, d에는 operator[]가 없습니다.
이 코드에는 다음과 같은 문제가 있습니다.
-
아시다시피, sort(d)에서 얻는 오류 메세지는 장황하고 아무 쓸모도 없습니다.
-
sort를 하기 위해서 선언문만 있는 것이 아니라, 정의를 제공해야 합니다. Generic Code로부터 그리고 우리가 코드를 구성하는 방법의 모델을 변경합니다.
-
sort을 하기 위한 요구사항이 함수 본체에 내포되어 있습니다. (즉, argument type을 가지고 요구사항이 맞는지 확인할 수 없습니다.)
-
sort(d)의 오류메세지는 템플릿이 인스턴스화 될 때만 나타납니다.
-
template<typename T> 표기법은 독특하고, 장황하며, 반복적입니다.
Concepts를 사용하면, template을 위한 template ( concepts는 template 으로 작성되기에 )을 지정하여, 문제의 근원에 도달할 수 있습니다. (주석을 통해)
// Concepts를 사용하는 Generic 한 코드
void sort (Sortable& c); // concepts : 정렬 가능한 모든 c를 허용
vector<string> vs = {"Hello", "New", "World"};
sort(vs); // Well, vs는 정렬 가능합니다.
double d = 7;
sort(d); // Ill-formed, d는 operator[]를 지원하지 않습니다.
이 코드는 위의 sort 예제와 유사합니다. 유일한 차이점은
-
Sortable의 경우, 사용자가 코드에서 의미를 지정했습니다. 즉 유형은 다음과 같은 경우 정렬 가능합니다.
- begin() 및 end()가 random_access_iterator 일것
- operator<를 사용하여 비교
-
이제 잘못된 호출( sort(d) )를 발견한 즉시 컴파일러가 주석에 표시된대로 오류 메세지를 표시합니다.
Concepts의 목표는 다음과 같습니다.
-
Generic Programming을 통한 코드가 아닌 간단한 코드와 같은 간단한 Generic Programming 코드
-
사용하기 쉽고, 작성하기가 그리 어렵지 않은 고급 Generic Programming 코드
Concepts 자체로는 코드 구성의 차이를 해결할 수 없습니다. 여전히 템플릿을 헤더에 넣어야 합니다.
그러나 그것은 모듈 [Rei16, C++20]에 의해 해결됩니다.
모듈에서 템플릿 유형은 추상 그래프로 표현되며, Concepts를 사용하여 템플릿 함수 호출을 확인합니다.
모듈에서 제공하는 인터페이스 ( 선언 ) 만 필요합니다
-> 이 내용이 위에서 말했던 sort를 하기 위해서 선언문만 있는 것이 아니라, 정의를 제공해야 합니다. 의 설명입니다.
2020/11/27 - [C++/Modern] - C++20) Concepts ( 콘셉트, 개념 ) - 2
'C++ > Modern' 카테고리의 다른 글
C++20) Concepts ( 콘셉트, 개념 ) - 3 (0) | 2020.11.28 |
---|---|
C++20) Concepts ( 콘셉트, 개념 ) - 2 (0) | 2020.11.27 |
C++20) Coroutine ( 코루틴 ) - 3 (0) | 2020.08.23 |
C++20) Coroutine ( 코루틴 ) - 2 (0) | 2020.08.21 |
C++20) Coroutine ( 코루틴 ) - 1 (0) | 2020.08.20 |