오보에블로그

[C++20] Concept 본문

C++ & C#/Modern C++

[C++20] Concept

(OBO) 2022. 1. 30. 23:48
728x90

[C++20] Concept

개요

  • C# 에서는 클래스나 함수에다가 Where 절을 통해 제네릭 타입에 대해서 어떤 조건을 부여해줄 수 있었다
  • C++ 에서도 그와 비슷한 기능이 생겼다.
  • 어떤 타입이 가져야하는 조건들을 정의하는 것이라고 보면 될 듯 하다.
  • concept를 통해 선언 해주고, requires 등을 통해 사용할 수 있다. 사용 방법은 여러가지이다.
    • concept : 제약/ 요구 조건을 기술 및 선언
    • requires : 해당 타입/템플릿이 가져야하는 제약 조건 지정
  • 이런 제약 조건들은 컴파일 타임에 결정되어, 빌드는 느려질 지언정, 실제 프로그램 실행시에는 빠르게 연산된다.
  • 즉, 컴파일 타임에 결정되는 제약 조건을 어떤 타입에 대해서 지정을 하는 것이다..!

예시 확인

  • 예시를 확인해보자. 다음 예제는 제네릭 타입 Tintegral 인 것으로 한정해주는 구문이다.
  • integral 부분이 바로 요구/제약 조건에 해당한다.

// template.h 에 아래처럼 integral 이 선언 되어 있다.
template<typename T> 
concept integral = is_integral_v<T>;

template<typename T>
requires integral<T>
void TestConcept1(T number)
{

}


TestConcept1(7); // pass
TestConcept1(3.14f); // error
  • 사용 방식은 총 4가지 이다.
// 1) Requires Clause(절)
template<typename T>
requires integral<T>
void TestConcept1(T number) { }

// 2) Trailing Requires Clause (뒤에 붙이기)
template<typename T>
void TestConcept2(T number) requires integral<T> { }

// 3) Constraint Template Parameter (강요된)
template<integral T>
void TestConcept2(T number){}

// 4) Abbreviated Function Template
void TestConcept4(integral auto number) { }
  • 제약 조건을 간단하게 논리 식으로도 지정할 수 있다.
// int 보다 자료형 사이즈가 큰 타입만 들어올 수 있음
template<typename T>
concept BiggerInteger = sizeof(T) > sizeof(int);

template<typename T>
void func(T t) requires BiggerInteger<T>
{

}

func(1); // error
func(static_cast<long long>(3)); // pass

#include <concepts>

  • 우리가 이렇게 다 구현을 해야하냐..! 아니다. 공식 문서를 보면 concepts 헤더파일 에 미리 제약/ 요구 조건들을 선언해주었다.
  • 이건 나중에 따로 포스트 해서 설명해도 좋을 것 같다.
  • 만약에 안불러와지면 이전처럼 구현 해주면 똑같이 동작한다.
  • 예시로 std::derived_from 을 확인해보자. 이것은 상속 받은 타입에 대한 제약 조건을 기술해놓았다.
  • 실제로 derived_from<Child, Parent> 를 출력해보면 참값으로 나온다.
class Parent { };
class Child : public Parent { }; // Parent 상속

template<typename T>
requires derived_from<T, Parent> // Parent로부터 파생된 T로만 받을 것이다.
void TestObj(T* obj)
{

}


Child* c = new Child();
TestObj(c); // pass
TestObj(314); // error
728x90

'C++ & C# > Modern C++' 카테고리의 다른 글

[C++20] Range  (0) 2022.01.31
[STL] STL 알고리즘 정리  (0) 2022.01.31
[C++20] Concepts library  (0) 2022.01.31