Skip to content

Commit 958d630

Browse files
committed
P2255R2 A type trait to detect reference binding to temporary
1 parent 4b1a735 commit 958d630

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

source/support.tex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@
669669
#define @\defnlibxname{cpp_lib_ranges_starts_ends_with}@ 202106L // also in \libheader{algorithm}
670670
#define @\defnlibxname{cpp_lib_ranges_zip}@ 202110L // also in \libheader{ranges}, \libheader{tuple}, \libheader{utility}
671671
#define @\defnlibxname{cpp_lib_raw_memory_algorithms}@ 201606L // also in \libheader{memory}
672+
#define @\defnlibxname{cpp_lib_reference_from_temporary}@ 202202L // also in \libheader{type_traits}
672673
#define @\defnlibxname{cpp_lib_remove_cvref}@ 201711L // also in \libheader{type_traits}
673674
#define @\defnlibxname{cpp_lib_result_of_sfinae}@ 201210L // also in \libheader{functional}, \libheader{type_traits}
674675
#define @\defnlibxname{cpp_lib_robust_nonmodifying_seq_ops}@ 201304L // also in \libheader{algorithm}

source/utilities.tex

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,11 @@
835835
\begin{codeblock}
836836
!is_convertible_v<U1, T1> || !is_convertible_v<U2, T2>
837837
\end{codeblock}
838+
This constructor is defined as deleted if
839+
\tcode{reference_constructs_from_temporary_v<first_type, U1\&\&>}
840+
is \tcode{true} or
841+
\tcode{reference_constructs_from_temporary_v<second_type, U2\&\&>}
842+
is \tcode{true}.
838843
\end{itemdescr}
839844

840845
\indexlibraryctor{pair}%
@@ -872,6 +877,11 @@
872877
!is_convertible_v<decltype(get<0>(@\exposid{FWD}@(p))), T1> ||
873878
!is_convertible_v<decltype(get<1>(@\exposid{FWD}@(p))), T2>
874879
\end{codeblock}
880+
The constructor is defined as deleted if
881+
\tcode{reference_constructs_from_temporary_v<first_type, decltype(get<0>(FWD(p)))>}
882+
is \tcode{true} or
883+
\tcode{reference_constructs_from_temporary_v<second_type, decltype(get<1>(FWD(p)))>}
884+
is \tcode{true}.
875885
\end{itemdescr}
876886

877887
\indexlibraryctor{pair}%
@@ -899,6 +909,11 @@
899909
\tcode{std::forward<U>(x)}.) This form of construction, whereby constructor
900910
arguments for \tcode{first} and \tcode{second} are each provided in a separate
901911
\tcode{tuple} object, is called \defn{piecewise construction}.
912+
\begin{note}
913+
If a data member of \tcode{pair} is of reference type and
914+
its initialization binds it to a temporary object,
915+
the program is ill-formed\iref{class.base.init}.
916+
\end{note}
902917
\end{itemdescr}
903918

904919
\indexlibrarymember{operator=}{pair}%
@@ -1694,6 +1709,11 @@
16941709
\begin{codeblock}
16951710
!conjunction_v<is_convertible<UTypes, Types>...>
16961711
\end{codeblock}
1712+
This constructor is defined as deleted if
1713+
\begin{codeblock}
1714+
(reference_constructs_from_temporary_v<Types, UTypes\&\&> || ...)
1715+
\end{codeblock}
1716+
is \tcode{true}.
16971717
\end{itemdescr}
16981718

16991719
\indexlibraryctor{tuple}%
@@ -1769,6 +1789,11 @@
17691789
\begin{codeblock}
17701790
!(is_convertible_v<decltype(get<I>(@\exposid{FWD}@(u))), Types> && ...)
17711791
\end{codeblock}
1792+
The constructor is defined as deleted if
1793+
\begin{codeblock}
1794+
(reference_constructs_from_temporary_v<Types, decltype(get<I>(@\exposid{FWD}@(u)))> || ...)
1795+
\end{codeblock}
1796+
is \tcode{true}.
17721797
\end{itemdescr}
17731798

17741799
\indexlibraryctor{tuple}%
@@ -1806,6 +1831,12 @@
18061831
!is_convertible_v<decltype(get<0>(@\exposid{FWD}@(u))), @$\tcode{T}_0$@> ||
18071832
!is_convertible_v<decltype(get<1>(@\exposid{FWD}@(u))), @$\tcode{T}_1$@>
18081833
\end{codeblock}
1834+
The constructor is defined as deleted if
1835+
\begin{codeblock}
1836+
reference_constructs_from_temporary_v<@$\tcode{T}_0$@, decltype(get<0>(@\exposid{FWD}@(u)))> ||
1837+
reference_constructs_from_temporary_v<@$\tcode{T}_1$@, decltype(get<1>(@\exposid{FWD}@(u)))>
1838+
\end{codeblock}
1839+
is \tcode{true}.
18091840
\end{itemdescr}
18101841

18111842
\indexlibraryctor{tuple}%
@@ -2367,6 +2398,13 @@
23672398
\end{itemdecl}
23682399

23692400
\begin{itemdescr}
2401+
\pnum
2402+
\mandates
2403+
If \tcode{tuple_size_v<remove_reference_t<Tuple>>} is 1,
2404+
then
2405+
\tcode{reference_constructs_from_temporary_v<T, decltype(get<0>(declval<Tuple>()))>}
2406+
is \tcode{false}.
2407+
23702408
\pnum
23712409
\effects
23722410
Given the exposition-only function:
@@ -14266,6 +14304,11 @@
1426614304
if \tcode{R} is \cv{}~\keyword{void}, otherwise
1426714305
\tcode{\placeholdernc{INVOKE}(f, t$_1$, t$_2$, $\dotsc$, t$_N$)} implicitly converted
1426814306
to \tcode{R}.
14307+
If
14308+
\tcode{reference_converts_from_temporary_v<R, decltype(\placeholdernc{INVOKE}(f, t$_1$, t$_2$, $\dotsc$, t$_N$)}
14309+
is true,
14310+
\tcode{\placeholdernc{INVOKE}<R>(f, t$_1$, t$_2$, $\dotsc$, t$_N$)}
14311+
is ill-formed.
1426914312

1427014313
\pnum
1427114314
\indextext{call wrapper}%
@@ -17427,6 +17470,9 @@
1742717470

1742817471
template<class T> struct has_unique_object_representations;
1742917472

17473+
template<class T, class U> struct reference_constructs_from_temporary;
17474+
template<class T, class U> struct reference_converts_from_temporary;
17475+
1743017476
// \ref{meta.unary.prop.query}, type property queries
1743117477
template<class T> struct alignment_of;
1743217478
template<class T> struct rank;
@@ -17706,6 +17752,12 @@
1770617752
template<class T>
1770717753
inline constexpr bool has_unique_object_representations_v
1770817754
= has_unique_object_representations<T>::value;
17755+
template<class T, class U>
17756+
inline constexpr bool @\libglobal{reference_constructs_from_temporary_v}@ =
17757+
reference_constructs_from_temporary<T, U>::value;
17758+
template<class T, class U>
17759+
inline constexpr bool @\libglobal{reference_converts_from_temporary_v}@ =
17760+
reference_converts_from_temporary<T, U>::value;
1770917761

1771017762
// \ref{meta.unary.prop.query}, type property queries
1771117763
template<class T>
@@ -17961,6 +18013,24 @@
1796118013
in the context of the corresponding definition
1796218014
notwithstanding the restrictions of~\ref{declval}.
1796318015

18016+
\pnum
18017+
For the purpose of defining the templates in this subclause,
18018+
let \tcode{\placeholder{VAL}<T>} for some type \tcode{T} be
18019+
an expression defined as follows:
18020+
\begin{itemize}
18021+
\item
18022+
If \tcode{T} is a reference or function type,
18023+
\tcode{\placeholder{VAL}<T>} is an expression
18024+
with the same type and value category as \tcode{declval<T>()}.
18025+
\item
18026+
Otherwise, \tcode{\placeholder{VAL}<T>} is a prvalue
18027+
that initially has type \tcode{T}.
18028+
\begin{note}
18029+
If \tcode{T} is cv-qualified,
18030+
the cv-qualification is subject to adjustment\iref{expr.type}.
18031+
\end{note}
18032+
\end{itemize}
18033+
1796418034
\begin{libreqtab3b}{Type property predicates}{meta.unary.prop}
1796518035
\\ \topline
1796618036
\lhdr{Template} & \chdr{Condition} & \rhdr{Preconditions} \\ \capsep

0 commit comments

Comments
 (0)