Document #: | P3047R0 |
Date: | 2024-02-15 |
Project: | Programming Language C++ |
Audience: |
Library Evolution |
Reply-to: |
Alisdair Meredith <ameredith1@bloomberg.net> |
Namespace std::relops
was
provided by the original C++ Standard, comprising a set of comparison
operator function templates that can provide a full set of comparison
operators for a type that supports a minimal subset of those operators.
That namespace was deprecated by C++20 as the operator rewrite rules
provide similar functionality directly in the language, and this paper
proposes removing that namespace from C++26.
At the start of the C++23 cycle, [P2139R2] tried to review each deprecated feature of C++ to see which we would benefit from actively removing and which might now be better undeprecated. Consolidating all this analysis into one place was intended to ease the (L)EWG review process but in return gave the author so much feedback that the next revision of the paper was not completed.
For the C++26 cycle, a much shorter paper, [P2863], will track the overall analysis, but for features that the author wants to actively progress, a distinct paper will decouple progress from the larger paper so that the delays on a single feature do not hold up progress on all.
This paper takes up the deprecated namespace
std::relops
and its comparison
operator templates, D.12
[depr.relops].
NOTE THAT THIS PAPER DOES NOT YET INCORPORATE FEEDBACK FROM THE KONA 2023 MEETING THAT REQUESTED A PAPER TO TRACK THIS PROGRESS SEPARATE FROM [P2863].
While feedback is welcome, we do not anticipate spending more committee time on this until R1 is available.
The std::rel_ops
namespace
was introduced in the original C++ Standard, so its removal would
potentially impact on code written against C++98 and later standards. It
was deprecated with the introduction of support for the 3-way comparison
“spaceship” operator in C++20, by paper [P0768R1].
As of publishing this paper, only the MSVC standard libraries gives deprecation warnings on the sample code in the Tony tables below.
Deprecated
|
Modern
|
---|---|
|
|
Tested with MSVC /W3
, and
-Wall -Wextra -Wdeprecated
with
Clang/libc++ and gcc/libstdc++
The orignal version of this paper erroneously claimed that all the
comparisons would be synthesized from the same two operations relied
upon by the rel_ops
operators.
In fact, those rules rely upon supplying the 3-way comparison operator,
rather than operator<
, as
illustrated above.
Note the three changes:
#include
a different
headerGiven the current lack of deprecation warnings, the tentative recommendation of this paper is to take no action for C++26 and encourage Standard Library maintainers to annotate their implementations as deprecated before the next standard cycle.
As the
using namespace std::rel_ops
idiom may be seen as encouraging bad hygiene, especially when applied at
global/namespace scope in a header, there may still be folks motivated
to write a paper expressing a stronger intent to remove this feature for
C++26.
As a historical note, the Standard Library specification itself used
to rely on std::rel_ops
to
provide the specification for any comparison operator if the necessary
wording were missing. However, as part of C++20, it was confirmed that
no current wording relies on that legacy fall-back, and the
corresponding as-if wording was removed.
Make the following changes to the C++ Working Draft. All wording is relative to [N4971], the latest draft at the time of writing.
1
In namespace std
, the following
names are reserved for previous standardization:
auto_ptr
,auto_ptr_ref
,random_shuffle
,raw_storage_iterator
,relops
,result_of
,result_of_t
,undeclare_reachable
,
andunexpected_handler
.1
Change: Remove namespace
relops
and all its contents.
Rationale: TBD
Effect on original feature: TBD
1
The header <utility>
(22.2.1) has the following additions:
namespace std::rel_ops {
template<class T> bool operator!=(const T&, const T&);
template<class T> bool operator> (const T&, const T&);
template<class T> bool operator<=(const T&, const T&);
template<class T> bool operator>=(const T&, const T&); }
2
To avoid redundant definitions of
operator!=
out of
operator==
and operators
>
,
<=
, and
>=
out of
operator<
, the library
provides the following:
template<class T> bool operator!=(const T& x, const T& y);
3
Preconditions: T
meets
the Cpp17EqualityComparable requirements (Table 28).
4
Returns: !(x == y)
.
template<class T> bool operator>(const T& x, const T& y);
5
Preconditions: T
meets
the Cpp17LessThanComparable requirements (Table 29).
6
Returns: y < x
.
template<class T> bool operator<=(const T& x, const T& y);
7
Preconditions: T
meets
the Cpp17LessThanComparable requirements (Table 29).
8
Returns:
!(y < x)
.
template<class T> bool operator>=(const T& x, const T& y);
9
Preconditions: T
meets
the Cpp17LessThanComparable requirements (Table 29).
10
Returns:
!(x < y)
.
All clause and subclause labels from ISO C++ 2023 (ISO/IEC 14882:2023, Programming Languages — C++) are present in this document, with the exceptions described below.
container.gen.reqmts see
container.requirements.general
depr.arith.conv.enum removed
depr.codecvt.syn removed
depr.default.allocator removed
depr.locale.stdcvt removed
depr.locale.stdcvt.general removed
depr.locale.stdcvt.req removed
depr.relops
removed
depr.res.on.required removed
depr.string.capacity removed
mismatch see alg.mismatch
Thanks to Michael Park for the pandoc-based framework used to transform this document’s source from Markdown.