std::reference_constructs_from_temporary
| Defined in header <type_traits>
|
||
template< class To, class From >
struct reference_constructs_from_temporary;
|
(since C++23) | |
Let V be std::remove_cv_t<From> if From is a scalar type or cv void, or From otherwise. If To is a reference type, and given a hypothetical expression e such that decltype(e) is V, the variable definition To ref(e); is well-formed and binds a temporary object to ref, then provides the member constant value equal to true. Otherwise, value is false.
If To is an lvalue reference type to a const- but not volatile-qualified object type or an rvalue reference type, both std::remove_reference_t<To> and std::remove_reference_t<From> must be complete types, cv void, or an arrays of unknown bound; otherwise the behavior is undefined.
If an instantiation of a template above depends, directly or indirectly, on an incomplete type, and that instantiation could yield a different result if that type were hypothetically completed, the behavior is undefined.
If the program adds specializations for std::reference_constructs_from_temporary or std::reference_constructs_from_temporary_v, the behavior is undefined.
Helper variable template
template< class To, class From >
constexpr bool reference_constructs_from_temporary_v =
std::reference_constructs_from_temporary<To, From>::value;
|
(since C++23) | |
Inherited from std::integral_constant
Member constants
value [static] |
true if To is a reference type, a From value can be bound to To in direct-initialization, and a temporary object would be bound to the reference, false otherwise (public static member constant) |
Member functions
operator bool |
converts the object to bool, returns value (public member function) |
operator() (C++14) |
returns value (public member function) |
Member types
| Type | Definition |
value_type
|
bool
|
type
|
std::integral_constant<bool, value>
|
Notes
std::reference_constructs_from_temporary can be used for rejecting some cases that always produce dangling references.
It is also possible to use member initializer list to reject binding a temporary object to a reference if the compiler has implemented 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
(C++11)(C++11)(C++11) |
checks if a type has a constructor for specific arguments (class template) |
constructs a new tuple (public member function of std::tuple<Types...>)
| |
constructs new pair (public member function of std::pair<T1,T2>)
| |
(C++17) |
construct an object with a tuple of arguments (function template) |
| checks if a reference is bound to a temporary in copy-initialization (class template) | |
| checks if a reference is bound to a temporary in direct-initialization (function) |