types_has_unique_object_representations

types_has_unique_object_representations (고유 객체 표현 보유 타입 여부)

이 페이지는 C++17에서 도입된 std::has_unique_object_representations 타입 트레이트에 대해 설명해요. 이 트레이트는 어떤 타입이 고유한 객체 표현(object representation)을 가지는지, 즉 같은 값을 가진 객체들이 항상 동일한 비트 표현을 가지는지 확인해 줘요. 이를 통해 타입을 바이트 배열로 해싱할 때 안전한지 판단할 수 있어요.

출처: cppreference

본문

헤더 <type_traits>에 정의됨
template < class T > struct has_unique_object_representations ; (C++17부터)

std::has_unique_object_representations는 UnaryTypeTrait예요.

T가 trivially copyable이고, 같은 값을 가진 T 타입의 두 객체가 항상 같은 객체 표현을 가진다면, 멤버 상수 valuetrue가 돼요. 그 외의 모든 타입에 대해서는 valuefalse예요.

이 트레이트의 목적상, 두 배열은 요소들이 같은 값을 가질 때 같은 값을 가지며, 두 non-union 클래스는 직접 하위 객체들이 같은 값을 가질 때 같은 값을 가지며, 두 공용체(union)는 활성 멤버가 같고 그 멤버의 값이 같을 때 같은 값을 가져요.

어떤 스칼라 타입이 이 트레이트를 만족하는지는 구현 정의(implementation-defined)예요. 하지만 패딩 비트를 사용하지 않는 unsigned (C++20 이전) 정수 타입은 고유한 객체 표현을 가질 것이 보장돼요.

std::remove_all_extents_t<T>가 (cv 한정될 수 있는) void가 아닌 불완전 타입이라면, 동작은 정의되지 않아요.

프로그램이 std::has_unique_object_representations 또는 std::has_unique_object_representations_v에 대한 특수화를 추가하면, 동작은 정의되지 않아요.

템플릿 매개변수

T - 확인할 타입

헬퍼 변수 템플릿

template < class T > constexpr bool has_unique_object_representations_v = has_unique_object_representations < T >:: value ; (C++17부터)

std::integral_constant에서 상속받음

멤버 상수

value [static] T가 고유한 객체 표현을 가지면 true, 아니면 false (공용 정적 멤버 상수)

멤버 함수

operator bool 객체를 bool로 변환하고 value를 반환해요 (공용 멤버 함수)
operator() (C++14) value를 반환해요 (공용 멤버 함수)

멤버 타입

타입 정의
value_type bool
type std::integral_constant<bool, value>

Notes

이 트레이트는 타입의 객체 표현을 바이트 배열로 해싱하여 해당 타입을 올바르게 해싱할 수 있는지 여부를 판단할 수 있도록 도입되었어요.

Feature-test 매크로 표준 기능
__cpp_lib_has_unique_object_representations 201606L (C++17) std::has_unique_object_representations

예제

#include <cstdint>
#include <type_traits>

struct unpadded
{
    std::uint32_t a, b;
};

struct likely_padded
{
    std::uint8_t c;
    std::uint16_t st;
    std::uint32_t i;
};

int main()
{
    // Every value of a char corresponds to exactly one object representation.
    static_assert(std::has_unique_object_representations_v<char>);
    // For IEC 559 floats, assertion passes because the value NaN has
    // multiple object representations.
    static_assert(!std::has_unique_object_representations_v<float>);
    
    // Should succeed in any sane implementation because unpadded
    // is typically not padded, and std::uint32_t cannot contain padding bits.
    static_assert(std::has_unique_object_representations_v<unpadded>);
    // Fails in most implementations because padding bits are inserted
    // between the data members c and st for the purpose of aligning st to 16 bits.
    static_assert(!std::has_unique_object_representations_v<likely_padded>);
    
    // Notable architectural divergence:
    static_assert(std::has_unique_object_representations_v<bool>); // x86
    // static_assert(!std::has_unique_object_representations_v<bool>); // ARM
}

결함 보고

다음 동작 변경 결함 보고서는 이전에 발표된 C++ 표준에 소급 적용되었어요.

DR 적용 대상 발표된 동작 올바른 동작
LWG 4113 C++17 요소 타입이 불완전해도 T는 미지원 경계 배열일 수 있었음 요소 타입이 완전해야 함

같이 보기

is_standard_layout (C++11) 타입이 표준 레이아웃 타입인지 확인해요 (클래스 템플릿)
hash (C++11) 해시 함수 객체 (클래스 템플릿)
has_unique_object_representations (C++26) 반영된 타입의 객체 표현의 모든 비트가 값에 기여하는지 확인해요 (함수)

더 알아보기 (Learn more)

cppreference