types_reference_constructs_from_temporary

types_reference_constructs_from_temporary (임시 객체로부터 참조 생성 여부 확인)

이 페이지에서는 C++23부터 도입된 std::reference_constructs_from_temporary 타입 특성에 대해 설명해요. 이 특성은 직접 초기화(direct-initialization) 과정에서 주어진 참조 타입이 임시 객체에 묶이는지 여부를 컴파일 타임에 판별하는 데 사용돼요. 특히 항상 댕글링 참조를 만드는 코드를 거부하고 싶을 때 유용해요.

출처: cppreference

본문

정의

Defined in header <type_traits>
template < class To , class From > struct reference_constructs_from_temporary ; (since C++23)

From이 스칼라 타입 또는 cv void라면 Vstd::remove_cv_t<From>으로, 그 외에는 From으로 정의해요. To가 참조 타입이고, decltype(e)V인 가상의 표현식 e가 주어졌을 때, 변수 정의 To ref(e);가 유효하고 임시 객체를 ref에 묶는다면 멤버 상수 valuetrue가 돼요. 그렇지 않으면 valuefalse예요.

To가 const(비휘발성) 한정 객체 타입에 대한 lvalue 참조 타입이거나 rvalue 참조 타입인 경우, std::remove_reference_t<To>std::remove_reference_t<From>는 모두 완전 타입(complete type), cv void, 또는 크기를 알 수 없는 배열이어야 해요. 그렇지 않으면 동작이 정의되지 않아요.

위 템플릿의 인스턴스화가 직접 또는 간접적으로 불완전 타입에 의존하고, 해당 타입이 가상으로 완성될 경우 인스턴스화 결과가 달라질 수 있다면 동작이 정의되지 않아요.

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

헬퍼 변수 템플릿

template < class To , class From > constexpr bool reference_constructs_from_temporary_v = std::reference_constructs_from_temporary < To , From >::value ; (since C++23)

std::integral_constant에서 상속됨

멤버 상수

value [static] To가 참조 타입이고, 직접 초기화에서 From 값이 To에 묶일 수 있으며, 임시 객체가 참조에 묶이는 경우 true, 그렇지 않으면 false (public static member constant)

멤버 함수

operator bool 객체를 bool로 변환하고 value를 반환해요 (public member function)
operator() (C++14) value를 반환해요 (public member function)

멤버 타입

Type Definition
value_type bool
type std::integral_constant<bool, value>

Notes

std::reference_constructs_from_temporary는 항상 댕글링 참조를 만드는 일부 경우를 거부하는 데 사용할 수 있어요. 또한 컴파일러가 CWG1696을 구현했다면 멤버 초기화 목록을 사용하여 임시 객체를 참조에 묶는 것을 거부할 수도 있어요.

Example

#include <type_traits>

static_assert
(
       std::reference_constructs_from_temporary_v<int&&, int>
    && std::reference_constructs_from_temporary_v<const int&, int>
    && !std::reference_constructs_from_temporary_v<int&&, int&&>
    && !std::reference_constructs_from_temporary_v<const int&, int&&>
    && std::reference_constructs_from_temporary_v<int&&, long&&>
    && std::reference_constructs_from_temporary_v<int&&, long>
);


struct S
{
    operator int() const;
    explicit operator const int&() const;
};

// For reference construction (direct init), explicit conversions are considered,
// so `operator const int&` is found, which is not classified as conversion from a temporary
static_assert(!std::reference_constructs_from_temporary_v<const int&, S>);

// For reference conversion (copy init), explicit conversions are disregarded,
// so `operator int` is found, which produces a temporary to which a `const int&` would bind
static_assert(std::reference_converts_from_temporary_v<const int&, S>);


struct Bad
{
    explicit operator int() const
    {
        return {};
    }
};

struct Fine
{
    explicit operator const int&() const
    {
        static int t;
        return t;
    }
};

template<typename T>
struct Wrapper
{
    T t;

    template<typename TT>
    Wrapper(TT&& tt)
        : t(tt) // The construction of T is done here...
    {
        // ... So if the conversion from TT to T results in a temporary,
        // that temporary will be destroyed when this function returns
        // I.e., it is guaranteed that t will be dangling

        static_assert(
            !std::reference_constructs_from_temporary_v<T, TT>,
            "Unconditionally dangling reference caused by explicit conversion"
        );
    }
};

int main()
{
    // Wrapper<const int&> w_bad(Bad{});
    Wrapper<const int&> w_fine(Fine{});
}

See also

is_constructible is_trivially_constructible is_nothrow_constructible (C++11) (C++11) (C++11) 특정 인자에 대한 생성자가 있는지 확인해요 (class template) [edit]
(constructor) 새로운 tuple을 생성해요 (public member function of std::tuple<Types...>) [edit]
(constructor) 새로운 pair를 생성해요 (public member function of std::pair<T1,T2>) [edit]
make_from_tuple (C++17) 튜플의 인자들로 객체를 생성해요 (function template) [edit]
reference_converts_from_temporary (C++23) 복사 초기화에서 참조가 임시 객체에 묶이는지 확인해요 (class template) [edit]
reference_constructs_from_temporary (C++26) 직접 초기화에서 참조가 임시 객체에 묶이는지 확인해요 (function) [edit]

더 알아보기 (Learn more)

cppreference