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라면 V를 std::remove_cv_t<From>으로, 그 외에는 From으로 정의해요. To가 참조 타입이고, decltype(e)가 V인 가상의 표현식 e가 주어졌을 때, 변수 정의 To ref(e);가 유효하고 임시 객체를 ref에 묶는다면 멤버 상수 value는 true가 돼요. 그렇지 않으면 value는 false예요.
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] |