From d235bb44a70e76eb911d12c24aa35110277ab362 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sat, 20 Jun 2026 10:41:05 +0200 Subject: [PATCH] P2953R5 Adding restrictions to defaulted assignment operator functions --- source/compatibility.tex | 40 +++++++++++++++++++++++++++++++ source/declarations.tex | 52 +++++++++++++++++++--------------------- 2 files changed, 65 insertions(+), 27 deletions(-) diff --git a/source/compatibility.tex b/source/compatibility.tex index 7f97796edc..a747ca0cbf 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -1,6 +1,46 @@ %!TEX root = std.tex \infannex{diff}{Compatibility} +\rSec1[diff.cpp26]{\Cpp{} and ISO \CppXXVI{}} + +\rSec2[diff.cpp26.general]{General} + +\pnum +\indextext{summary!compatibility with ISO \CppXXVI{}}% +Subclause \ref{diff.cpp26} lists the differences between \Cpp{} and +ISO \CppXXVI{}, +by the chapters of this document. + +\rSec2[diff.cpp26.dcl]{\ref{dcl}: declarations} + +\diffref{dcl.fct.def.default} +\change +It is no longer valid +for explicitly defaulted assignment operators to have a +\grammarterm{cv-qualifier-seq} or \tcode{\&\&} \grammarterm{ref-qualifier}, or +for an explicitly defaulted move assignment operator +to have a parameter of type ``reference to \tcode{T}'' +where \tcode{T} is cv-qualified. +\rationale +Removal of rarely-used and confusing feature. +\effect +A valid \CppXXVI{} program +which uses these features on an explicitly defaulted assignment operator +is ill-formed. +\begin{example} +\begin{codeblock} +struct S { + S& operator=(const S&) && = default; // ill-formed; previously well-formed +}; +struct T { + T& operator=(const T&) const = default; // ill-formed; previously well-formed but deleted +}; +struct U { + U& operator=(const U&&) = default; // ill-formed; previously well-formed but deleted +}; +\end{codeblock} +\end{example} + \rSec1[diff.cpp23]{\Cpp{} and ISO \CppXXIII{}} \rSec2[diff.cpp23.general]{General} diff --git a/source/declarations.tex b/source/declarations.tex index 627360a226..3c16592b90 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -7005,41 +7005,39 @@ \end{itemize} \pnum -An explicitly defaulted special member function $\tcode{F}_1$ -is allowed to differ from -the corresponding special member function $\tcode{F}_2$ -that would have been implicitly declared, as follows: +The program is ill-formed +if an explicitly defaulted special member function $\tcode{F}_1$ +of class \tcode{C} +differs from the corresponding special member function $\tcode{F}_2$ +that would have been implicitly declared +other than as follows: \begin{itemize} \item - $\tcode{F}_1$ and $\tcode{F}_2$ may have differing \grammarterm{ref-qualifier}{s}; + if $\tcode{F}_1$ is an assignment operator, + it may have the \tcode{\&} \grammarterm{ref-qualifier}; \item - if $\tcode{F}_2$ has an implicit object parameter of - type ``reference to \tcode{C}'', - $\tcode{F}_1$ may be an explicit object member function whose - explicit object parameter is of (possibly different) type ``reference to \tcode{C}'', + if $\tcode{F}_2$ is an assignment operator + (which has an implicit object parameter + of type ``lvalue reference to \tcode{C}''), + $\tcode{F}_1$ may have an explicit object parameter + of type ``lvalue reference to \tcode{C}'', in which case the type of $\tcode{F}_1$ would differ from the type of $\tcode{F}_2$ in that the type of $\tcode{F}_1$ has an additional parameter; \item - $\tcode{F}_1$ and $\tcode{F}_2$ may have differing exception specifications; and + $\tcode{F}_1$ and $\tcode{F}_2$ may have differing exception specifications; \item - if $\tcode{F}_2$ has a non-object parameter of type \tcode{const C\&}, - the corresponding non-object parameter of $\tcode{F}_1$ may be of - type \tcode{C\&}. -\end{itemize} -If the type of $\tcode{F}_1$ differs from the type of $\tcode{F}_2$ in a way -other than as allowed by the preceding rules, then: -\begin{itemize} -\item - if $\tcode{F}_1$ is an assignment operator, and - the return type of $\tcode{F}_1$ differs from - the return type of $\tcode{F}_2$ or - $\tcode{F}_1${'s} non-object parameter type is not a reference, - the program is ill-formed; -\item - otherwise, if $\tcode{F}_1$ is explicitly defaulted on its first declaration, - it is defined as deleted; + if $\tcode{F}_2$ has a non-object parameter + of type ``lvalue reference to const \tcode{C}'', + the corresponding non-object parameter of $\tcode{F}_1$ may be + of type ``lvalue reference to \tcode{C}''; and \item - otherwise, the program is ill-formed. + if $\tcode{F}_2$ has a non-object parameter + of type ``lvalue reference to \tcode{C}'', + the corresponding non-object parameter of $\tcode{F}_1$ may be + of type ``lvalue reference to const \tcode{C}''; + in this case only, $\tcode{F}_1$ is defined as deleted + if it is explicitly defaulted on its first declaration and + the program is ill-formed otherwise. \end{itemize} \pnum