본문으로 바로가기

C++20) Concepts ( 콘셉트, 개념 ) - 1

category C++/Modern 2020. 11. 25. 03:16

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

2020/11/28 - [C++/Modern] - C++20) Concepts ( 콘셉트, 개념 ) - 3

2020/11/29 - [C++/Modern] - C++20) Concepts ( 콘셉트, 개념 ) - 4

'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