std::derived_from

std::derived_from (파생 관계 개념)

Derived 타입이 Base 타입에서 공개적이고 명확하게 파생됐는지(또는 동일 타입인지)를 명세하는 개념(concept)이에요. std::is_base_of와 달리 private·protected 상속은 만족하지 않아요. C++20부터 있어요.

출처: cppreference

본문

<concepts> 헤더에 정의돼 있어요.

template< class Derived, class Base >
concept derived_from =
    std::is_base_of_v<Base, Derived> &&
    std::is_convertible_v<const volatile Derived*, const volatile Base*>;

개념 derived_from<Derived, Base>BaseDerived이거나 Derived의 공개적이고 명확한 기반 클래스(클래스 타입)일 때(그리고 그때만) 만족돼요. cv 한정자는 무시해요.

BaseDerived의 private 또는 protected 기반 클래스일 때 이 동작은 std::is_base_of와 다르다는 점에 주의해요. is_base_of는 private 상속도 참으로 보지만, derived_from은 공개 상속이 아니면 거짓이에요.

예제를 보면요.

#include <concepts>

class A {};

class B : public A {};

class C : private A {};

// std::derived_from == true는 공개 상속 또는 정확히 같은 클래스일 때만
static_assert(std::derived_from<B, B> == true);      // 같은 클래스: true
static_assert(std::derived_from<int, int> == false); // 같은 기본 타입: false
static_assert(std::derived_from<B, A> == true);      // 공개 상속: true
static_assert(std::derived_from<C, A> == false);     // private 상속: false

// std::is_base_of는 private 상속에서도 true
static_assert(std::is_base_of_v<B, B> == true);      // 같은 클래스: true
static_assert(std::is_base_of_v<A, B> == true);      // 공개 상속: true
static_assert(std::is_base_of_v<A, C> == true);      // private 상속: true

is_convertible_v<const volatile Derived*, const volatile Base*> 검사 덕분에 private 상속은 업캐스트가 불가능하므로 derived_from이 거짓이 돼요.

참고 문헌

  • C++23 표준 (ISO/IEC 14882:2024): 18.4.3 Concept derived_from [concept.derived]
  • C++20 표준 (ISO/IEC 14882:2020): 18.4.3 Concept derived_from [concept.derived]

더 알아보기 (Learn more)

cppreference