types_is_layout_compatible
types_is_layout_compatible (두 타입의 레이아웃 호환 여부 판정)
이 페이지에서는 C++20에서 도입된 std::is_layout_compatible 특성(trait)에 대해 설명해요. 이 특성은 두 타입이 레이아웃 호환(layout-compatible)인지 여부를 컴파일 타임에 판단하는 데 사용해요. 저수준 메모리 처리나 서로 다른 타입 간의 상호 운용이 필요한 코드에서 특히 유용해요.
출처: cppreference
본문
정의 (Definition)
<type_traits> 헤더에 정의되어 있어요.
template < class T , class U > struct is_layout_compatible ;
C++20부터 사용할 수 있어요.
설명 (Description)
T와 U가 레이아웃 호환 타입이라면 멤버 상수 value는 true가 되고, 그렇지 않으면 false가 돼요.
모든 타입은 자신의 cv 한정 버전과 레이아웃 호환이에요. 객체 타입이 아니어도 마찬가지예요.
T나 U가 완전 타입(complete type)이 아니거나, (cv 한정된) void이거나, 경계를 알 수 없는 배열이면 동작이 정의되지 않아요.
템플릿 인스턴스화가 불완전 타입에 직간접적으로 의존하고, 그 타입이 가상으로 완성되었을 때 결과가 달라질 수 있다면 동작이 정의되지 않아요.
프로그램에서 std::is_layout_compatible 또는 std::is_layout_compatible_v에 대한 특수화를 추가하면 동작이 정의되지 않아요.
헬퍼 변수 템플릿 (Helper variable template)
template < class T , class U > constexpr bool is_layout_compatible_v = is_layout_compatible < T , U >:: value ; (C++20부터)
std::integral_constant에서 상속됨
멤버 상수
| 멤버 | 설명 |
|---|---|
value [static] |
T와 U가 레이아웃 호환이면 true, 아니면 false (공용 정적 멤버 상수) |
멤버 함수
| 함수 | 설명 |
|---|---|
operator bool |
객체를 bool로 변환하며 value를 반환해요 (공용 멤버 함수) |
operator() (C++14) |
value를 반환해요 (공용 멤버 함수) |
멤버 타입
| 타입 | 정의 |
|---|---|
value_type |
bool |
type |
std :: integral_constant < bool , value > |
참고 사항 (Notes)
- 부호 있는 정수 타입과 그에 대응하는 부호 없는 정수 타입은 레이아웃 호환이 아니에요.
char는signed char나unsigned char와도 레이아웃 호환이 아니에요. - 최상위 cv 한정을 무시했을 때 같은 타입이 아니라면 유사한 타입도 레이아웃 호환이 아니에요.
- 열거형 타입과 그 기반 타입(underlying type)은 레이아웃 호환이 아니에요.
- 레이아웃 호환되지만 요소 타입이 다른 배열 타입은 길이가 같아도 레이아웃 호환이 아니에요.
기능 테스트 매크로 (Feature-test macro)
| 매크로 | 값 | 표준 | 기능 |
|---|---|---|---|
__cpp_lib_is_layout_compatible |
201907L |
(C++20) | std::is_layout_compatible |
예제 (Example)
#include <type_traits>
static_assert
(""
&& std::is_layout_compatible_v<const void, volatile void>
&& !std::is_layout_compatible_v<long, unsigned long>
&& std::is_layout_compatible_v<char*, char* const>
&& !std::is_layout_compatible_v<char*, const char*>
);
struct Foo
{
int x;
char y;
};
struct FooNua
{
int x;
[[no_unique_address]] char y;
};
class Bar
{
const int u{42};
volatile char v{'*'};
};
static_assert
(""
&& std::is_layout_compatible_v<Foo, Bar>
&& !std::is_layout_compatible_v<Foo[2], Bar[2]>
&& !std::is_layout_compatible_v<Foo, FooNua> //Note [1]
);
//[1] MSVC erroneously fails this assert
enum E0 : int {};
enum class E1 : int {};
static_assert
(""
&& !std::is_layout_compatible_v<int, E0>
&& std::is_layout_compatible_v<E0, E1>
&& !std::is_layout_compatible_v<int, E1>
);
int main() {}
같이 보기 (See also)
| is_standard_layout (C++11) | 타입이 표준 레이아웃 타입인지 확인해요 (클래스 템플릿) |
| is_layout_compatible_type (C++26) | 두 반영된 타입이 레이아웃 호환인지 확인해요 (함수) |