Section: 29.2 [numeric.requirements] Status: C++20 Submitter: Tim Song Opened: 2018-07-05 Last modified: 2021-02-25
Priority: 0
View all other issues in [numeric.requirements].
View all issues with C++20 status.
Discussion:
29.2 [numeric.requirements] contains some very old wording that hasn't been changed since C++98 except for issue 2699. As a result, it is at once over- and under-restrictive. For example:
operator&
for class types, but not enumeration types; andT
's special member functions, but
doesn't require that copying produces an equivalent value to the original.We can significantly clean up this wording by using the existing named requirements. For ease of review, the following table provides a side-by-side comparison of the current and proposed wording.
Before | After |
---|---|
A C++ program shall instantiate these components only with a type T
that satisfies the following requirements: [Footnote … ] |
A C++ program shall instantiate these components only with a cv-unqualified object type T
that satisfies the Cpp17DefaultConstructible, Cpp17CopyConstructible, Cpp17CopyAssignable,
and Cpp17Destructible |
(1.1) — T is not an abstract class (it has no pure virtual member functions); |
Cpp17DefaultConstructible |
(1.2) — T is not a reference type; (1.3) — T is not cv-qualified; |
Implied by "cv-unqualified object type" |
(1.4) — If T is a class, it has a public default constructor; |
Cpp17DefaultConstructible |
(1.5) — If T is a class, it has a public copy constructor
with the signature T::T(const T&) ; |
Cpp17CopyConstructible |
(1.6) — If T is a class, it has a public destructor; |
Cpp17Destructible |
(1.7) — If T is a class, it has a public copy assignment operator whose signature is either
T& T::operator=(const T&) or T& T::operator=(T); |
Cpp17CopyAssignable |
(1.8) — If T is a class, its assignment operator, copy and default constructors, and destructor
shall correspond to each other in the following sense:(1.8.1) — Initialization of raw storage using the copy constructor on the value of T() , however
obtained, is semantically equivalent to value-initialization of the same raw storage.(1.8.2) — Initialization of raw storage using the default constructor, followed by assignment, is semantically equivalent to initialization of raw storage using the copy constructor. (1.8.3) — Destruction of an object, followed by initialization of its raw storage using the copy constructor, is semantically equivalent to assignment to the original object. [Note: […] — end note] |
These requirements are implied by Cpp17CopyConstructible and Cpp17CopyAssignable's requirement that the value of the copy is equivalent to the source. |
(1.9) — If T is a class, it does not overload unary operator& . |
omitted now that we have std::addressof |
[2019-01-20 Reflector prioritization]
Set Priority to 0 and status to Tentatively Ready
Proposed resolution:
This wording is relative to the post-Rapperswil 2018 working draft.
Edit 29.2 [numeric.requirements] p1 as indicated, striking the entire bulleted list:
-1- The
complex
andvalarray
components are parameterized by the type of information they contain and manipulate. A C++ program shall instantiate these components only with a cv-unqualified object typeT
that satisfies the Cpp17DefaultConstructible, Cpp17CopyConstructible, Cpp17CopyAssignable, and Cpp17Destructiblefollowingrequirements (16.4.4.2 [utility.arg.requirements]).:[Footnote: … ]
(1.1) —T
is not an abstract class (it has no pure virtual member functions);[…](1.9) — IfT
is a class, it does not overload unaryoperator&
.
Edit 29.6.2.4 [valarray.access] p3-4 as indicated:
const T& operator[](size_t n) const; T& operator[](size_t n);-1- Requires:
-2- Returns: […] -3- Remarks: The expressionn < size()
.evaluates to
&addressof(a[i+j]) ==&addressof(a[i]) + jtrue
for allsize_t i
andsize_t j
such thati+j < a.size()
. -4- The expressionevaluates to
&addressof(a[i]) !=&addressof(b[j])true
for any two arraysa
andb
and for anysize_t i
andsize_t j
such thati < a.size()
andj < b.size()
. [Note: […] — end note ]