types_is_polymorphic
types_is_polymorphic (다형성 클래스 판별)
std::is_polymorphic은 주어진 타입 T가 다형성 클래스인지 컴파일 타임에 확인하는 C++ 타입 특성(type trait)이에요. 이 특성을 사용하면 타입이 가상 함수를 하나 이상 선언하거나 상속받는 비공용체 클래스인지 판별할 수 있어요. 템플릿 메타프로그래밍에서 타입의 성질에 따라 조건부 코드를 생성할 때 유용하게 활용돼요.
출처: cppreference
본문
정의와 요구 사항
<type_traits> 헤더에 정의되어 있으며, C++11부터 사용할 수 있어요.
template< class T > struct is_polymorphic;
std::is_polymorphic은 UnaryTypeTrait이에요. T가 다형성 클래스, 즉 가상 함수를 하나 이상 선언하거나 상속받는 비공용체(non-union) 클래스라면 멤버 상수 value는 true가 돼요. 그 외의 모든 타입에 대해서는 value가 false예요.
T가 불완전한 비공용체 클래스 타입이라면 동작이 정의되지 않아요. 또한 프로그램에서 std::is_polymorphic이나 std::is_polymorphic_v에 대한 특수화를 추가하면 동작이 정의되지 않아요.
템플릿 매개변수
| T | - | 확인할 타입 |
|---|
헬퍼 변수 템플릿
C++17부터 다음과 같은 헬퍼 변수 템플릿이 제공돼요.
template< class T > constexpr bool is_polymorphic_v = is_polymorphic<T>::value;
std::integral_constant로부터 상속
std::is_polymorphic은 std::integral_constant<bool, value>를 상속받아요.
멤버 상수
| value [static] | T가 다형성 클래스 타입이면 true, 아니면 false (공용 정적 멤버 상수) |
|---|
멤버 함수
| operator bool | 객체를 bool로 변환하며 value를 반환해요 (공용 멤버 함수) |
|---|---|
| operator() (C++14) | value를 반환해요 (공용 멤버 함수) |
멤버 타입
| Type | Definition |
|---|---|
| value_type | bool |
| type | std::integral_constant<bool, value> |
가능한 구현
다음은 dynamic_cast를 이용한 가능한 구현 예시예요.
namespace detail { template < class T > std :: true_type detect_is_polymorphic ( decltype ( dynamic_cast < const volatile void *> ( static_cast < T *> ( nullptr ))) ); template < class T > std :: false_type detect_is_polymorphic (...); } // namespace detail template < class T > struct is_polymorphic : decltype ( detail :: detect_is_polymorphic < T > ( nullptr )) {};
예제
#include <type_traits>
struct A { int m; };
static_assert(!std::is_polymorphic_v<A>);
struct B { virtual void foo(); };
static_assert(std::is_polymorphic_v<B>);
struct C : B {};
static_assert(std::is_polymorphic_v<C>);
struct D { virtual ~D() = default; };
static_assert(std::is_polymorphic_v<D>);
// Virtual inheritance does not make a type polymorphic.
struct E : A {};
static_assert(!std::is_polymorphic_v<E>);
struct F : virtual A {};
static_assert(!std::is_polymorphic_v<F>);
struct AX : A {};
struct AY : A {};
struct XY : virtual AX, virtual AY {};
static_assert(!std::is_polymorphic_v<XY>);
int main() {}
결함 보고서
다음의 동작 변경 결함 보고서는 이전에 발표된 C++ 표준에 소급 적용됐어요.
| DR | 적용 대상 | 발표된 동작 | 올바른 동작 |
|---|---|---|---|
| LWG 2015 | C++11 | T가 불완전한 공용체 타입이면 동작이 정의되지 않았음 | 이 경우 기본 특성은 std::false_type임 |
같이 보기
| is_class (C++11) | 타입이 비공용체 클래스 타입인지 확인해요 (클래스 템플릿) |
|---|---|
| is_abstract (C++11) | 타입이 추상 클래스 타입인지 확인해요 (클래스 템플릿) |
| has_virtual_destructor (C++11) | 타입에 가상 소멸자가 있는지 확인해요 (클래스 템플릿) |
| is_polymorphic_type (C++26) | 반영된 타입이 다형성 클래스 타입인지 확인해요 (함수) |