types_is_base_of
types_is_base_of (기반 클래스 여부 판별)
std::is_base_of는 한 타입이 다른 타입의 기반 클래스인지, 또는 두 타입이 같은 비공용체 클래스인지 확인하는 타입 특성(type trait)이에요. 컴파일 타임에 상속 관계를 판별해서 true 또는 false 값을 제공해요. C++11부터 사용할 수 있고, C++17부터는 변수 템플릿 is_base_of_v도 제공돼요.
출처: cppreference
본문
헤더
<type_traits>에 정의됨 |
||
|---|---|---|
template < class Base , class Derived > struct is_base_of ; |
(C++11부터) |
std::is_base_of는 이진 타입 특성(BinaryTypeTrait)이에요.
Derived가 Base에서 파생되었거나, 둘 다 cv 한정을 무시했을 때 같은 비공용체 클래스라면, 멤버 상수 value는 true가 돼요. 그 외에는 false예요.
Base와 Derived가 둘 다 비공용체 클래스 타입이고, cv 한정을 무시했을 때 서로 다른 타입이라면 Derived는 완전한 타입(complete type)이어야 해요. 그렇지 않으면 동작이 정의되지 않아요.
프로그램이 std::is_base_of 또는 std::is_base_of_v(C++17부터)에 대한 특수화를 추가하면 동작이 정의되지 않아요.
헬퍼 변수 템플릿
template < class Base , class Derived > constexpr bool is_base_of_v = is_base_of < Base , Derived >:: value ; |
(C++17부터) |
|---|
std::integral_constant에서 상속됨
멤버 상수
value [static] |
Derived가 Base에서 파생되었거나 둘 다 같은 비공용체 클래스이면 true (cv 한정 무시), 그 외에는 false (공용 static 멤버 상수) |
|---|
멤버 함수
operator bool |
객체를 bool로 변환하고 value를 반환해요 (공용 멤버 함수) |
|---|---|
operator() (C++14) |
value를 반환해요 (공용 멤버 함수) |
멤버 타입
| 타입 | 정의 |
|---|---|
value_type |
bool |
type |
std :: integral_constant < bool , value > |
노트
std::is_base_of<A, B>::value는 A가 B의 private, protected, 또는 모호한(ambiguous) 기반 클래스인 경우에도 true예요. 많은 상황에서 std::is_convertible<B*, A*>가 더 적절한 검사가 될 수 있어요.
어떤 클래스도 자기 자신의 기반 클래스는 아니지만, std::is_base_of<T, T>::value는 true예요. 이 특성의 의도가 "is-a" 관계를 모델링하는 것이고, T는 T이기 때문이에요. 그럼에도 std::is_base_of<int, int>::value는 false인데, 이 특성이 모델링하는 관계에는 클래스만 참여할 수 있기 때문이에요.
가능한 구현
namespace details {
template <typename B>
std::true_type test_ptr_conv(const volatile B*);
template <typename>
std::false_type test_ptr_conv(const volatile void*);
template <typename B, typename D>
auto test_is_base_of(int) -> decltype(test_ptr_conv<B>(static_cast<D*>(nullptr)));
template <typename, typename>
auto test_is_base_of(...) -> std::true_type; // private 또는 ambiguous base
}
template <typename Base, typename Derived>
struct is_base_of :
std::integral_constant<
bool,
std::is_class<Base>::value &&
std::is_class<Derived>::value &&
decltype(details::test_is_base_of<Base, Derived>(0))::value
> {};
예제
#include <type_traits>
class A {};
class B : A {};
class C : B {};
class D {};
union E {};
using I = int;
static_assert
(
std::is_base_of_v<A, A> == true &&
std::is_base_of_v<A, B> == true &&
std::is_base_of_v<A, C> == true &&
std::is_base_of_v<A, D> != true &&
std::is_base_of_v<B, A> != true &&
std::is_base_of_v<E, E> != true &&
std::is_base_of_v<I, I> != true
);
int main() {}
결함 보고서
다음 동작 변경 결함 보고서는 이전에 발표된 C++ 표준에 소급 적용되었어요.
| DR | 적용 대상 | 발표된 동작 | 올바른 동작 |
|---|---|---|---|
| LWG 2015 | C++11 | Derived가 불완전한 공용체 타입이면 동작이 정의되지 않을 수 있었어요 |
이 경우 기본 특성은 std::false_type이에요 |
같이 보기
is_virtual_base_of (C++26) |
한 타입이 다른 타입의 가상 기반 클래스인지 확인해요 (클래스 템플릿) [edit] |
|---|---|
is_convertible is_nothrow_convertible (C++11) (C++20) |
한 타입이 다른 타입으로 변환될 수 있는지 확인해요 (클래스 템플릿) [edit] |
derived_from (C++20) |
한 타입이 다른 타입에서 파생되었음을 명시해요 (컨셉) [edit] |
is_base_of_type (C++26) |
두 리플렉션이 한 타입이 다른 타입의 기반인 관계를 나타내는지 확인해요 (함수) [edit] |