1. Revision History
1.1. Revision 0
Initial Release. 🥳
2. Motivation
Within the standard library, there are multiple instances of phrases such as
"If T is the same type as U, the program is ill-formed", or This function
does not participate in overload resolution unless the following contrainsts
are true, followed by something like
. It
would, honestly, be easier to express these with concepts. Furthermore, the
inversion of the
concept is much more common than
itself when trying to constrain signatures of template types. Additionally, in
the realm of ranges, users tend to need to express that similar types are ok
in some instances, while distinct (or different, see § 3 Request for Feedback regarding
this phrase) are fairly common. In the author’s work codebase, the inversion of
appears about 20 times for each time where
is
used. While it is still early days regarding concepts, it would not be
surprising if other code bases had similar ratios, though most likely they are
not as extreme.
In the interest of symmetry with
and
, this paper
provides both
and
, although the wording found
below only redefines wording in terms of
, and
.
3. Request for Feedback
Currently, there is some ambiguity with the naming of
and
. When something is distinct, it typically implies that it is
set apart and completely dissimilar to something else. However, the direct
antonym of same in english is different. The author is fine with swapping
the definition of
and
, but will defer to
any consensus from LEWG or LWG if it is deemed necessary to swap their
definitions.
4. Wording
The following wording is based off of the text found at https://eel.is/c++draft as of 2020-07-11.
The following is to be modified (according to a value as decided by LWG) in
17.3.2 Header
synopsis [version.syn], statement 2
#define __cpp_lib_concepts 20����L
202002L
The following is to be added to 18.3 Header
synopsis [concepts.syn]
// [concept.different], concept different_from
template < class T , class U >
see below
concept different_from =
;
// [concept.similar], concept similar_to
template < class T , class U >
see below
concept similar_to =
;
// [concept.distinct], concept distinct_from
template < class T , class U >
see below
concept distinct_from =
;
The following is to be added to 18.4 Language-related concepts [concepts.lang]
18.4.� Concept [concept.different]
different_from
template < class T , class U >
concept different_from = not same_as < T , U > ;
18.4.� Concept [concept.similar]
similar
template < class T , class U >
concept similar_to = same_as < remove_cvref_t < T > , remove_cvref_t < U >> ;
18.4.� Concept [concept.distinct]
distinct_from
template < class T , class U >
concept distinct_from = not similar_to < T , U > ;
The following is to be modified in 20.6.3.1 Constructors [optional.ctor], statement 22
Constraints:is
is_constructible_ v < T , U > true
,,
is_same_v < remove_ cvref_t < U >
in_place_ t > is
distinct_from < U , in_place_t > false
true
, and
is_same_v < remove_ cvref_t < U > , optional > is
distinct_from < U , optional > .false
true
The following is to be modified in 20.6.3.3 Assignment [optional.assign], statement 14
Constraints:
is_same_v < remove_cvref_t < U > , optional > is
distinct_from < U , optional > false
true
The following is to be modified in 20.7.3.3 Assignment [variant.assign], statement 12.1
—
is_same_v < remove_cvref_t < T > , variant > is
distinct_from < T , variant > false
true
.
The following is to be modified in 20.8.3.1 Construction and destruction [any.cons], statement 6
Constraints:is not the same type as
VT
any is
distinct_from < T , any > true
The following is to be modified in 20.14.5.1 Constructors and destructor [refwrap.const], statement 2
Constraints: The expression FUNis well-formed and
( declval < U > ())
is_same_v < remove_cvref_t < U > , reference_wrapper > is
distinct_from < U , reference_wrapper > false
true
The following is to be modified from 21.2 Character traits [char.traits], statement 3
To specialize those templates to generate a string, string view, or iostream class to handle a particular character container type ([defns.character.container]), that and its related character traits class
C are passed as a pair of parameters to the string, string view, or iostream template as parameters
X and
charT .
traits IfIfis not the same type as
X :: char_type , the program is ill-formed.
C is
different_from < X :: char_type , C > true
, the program is ill-formed
The following is to be modified from 21.3.2.1 General requirements [string.require], statement 3
In every specialization, the type
basic_string < charT , traits , Allocator > shall name the same type as
allocator_traits < Allocator >:: value_type . Every object of type
charT uses an object of type
basic_string < charT , traits , Allocator > to allocate and free storage for the contained
Allocator objects as needed. The
charT object used is obtained as described in [container.requirements.general]. In every specialization
Allocator , the type
basic_string < charT , traits , Allocator > shall mee the character traits requirements ([char.traits]). [Note: The program is ill-formed if
traits is not the same type as
traits :: char_type
charT is
different_from < traits :: char_type , charT > true
—end note]
The following is to be modified from 21.4.2 Class template
[string.view.template], statement 1
In every specialization, the type
basic_string_view < charT , traits > shall mee the character traits requirements ([char.traits]). [Note: The program is ill-formed if
traits is not the same type as
traits :: char_type
charT is
different_from < traits :: char_type , charT > true
—end note]
The following is to be removed from 24.5.1 Helper concepts [range.utility.helpers]
template < class T , class U >
concept not - same - as = // exposition only
! same_as < remove_cvref_t < T > , remove_cvref_t < U >> ;
The following is to be modified in 24.5.3 Sub-ranges [range.subrange]
template < class From , class To >
concept convertible - to - non - slicing = // exposition only
convertible_to < From , To > &&
! ( is_pointer_v < decay_t < From >> &&
is_pointer_v < decay_t < To >> &&
not - same - as < remove_pointer_t < decay_t < From >> , remove_pointer_t < decay_t < To >>> );
distinct_from < remove_pointer_t < decay_t < From >> , remove_pointer_t < decay_t < To >>> );
The following is to be modified in 24.5.3.1 Constructors and conversions [range.subrange.ctor]
template < not - same - as < subrange > R >
template < distinct_from < subrange > R >
requires borrowed_range < R > &&
convertible - to - non - slicing < iterator_t < R > , I > &&
convertible_ to < sentinel_t < R > , S >
constexpr subrange ( R && r ) requires ( ! StoreSize || sized_ range < R > );
template < not - same - as < subrange > PairLike >
template < distinct_from < subrange > PairLike >
requires pair - like - convertible - from < PairLike , const I & , const S &>
constexpr operator PairLike () const ;
The following is to be modified in 24.7.3.1 Class template ref_view [range.ref.view]
Inside of statement 1
template < not - same - as < ref_view > T >
template < distinct_from < ref_view > T >
requires /* see below */
constexpr ref_view ( T && t );
At the definition preceeding statement 2
template < not - same - as < ref_view > T >
template < distinct_from < ref_view > T >
requires /* see below */
constexpr ref_view ( T && t );
The following is to be modified in 29.3.2 Overview [iostream.forward.overview], statement 6
[Note: For each of the class tempaltes above, the program is ill-formed ifis not the same type as
traits :: char_type
charT is
different_from < traits :: char_type , charT > true
([char.traits]) —end note]
The following is to be modified in 32.4.2.2 Constructors [thread.thread.constr], statement 3
Constraints:is not the same type as
remove_cvref_t < F >
thread is
distinct_from < F , thread > true
The following is to be modified in 32.4.3.1 Constructors, move, and assignment, statement 3
Constraints:is not the same type as
remove_cvref_t < F >
jthread is
distinct_from < F , jthread > true
The following is to be modified in 32.9.10.1 Member functions [futures.task.members], statement 2
Constraints:is not the same type as
remove_cvref_t < F >
packaged_task < R ( ArgTypes ...) > is
distinct_from < F , packaged_task > true
The following is to be removed from the Index of library concepts
not-same-as[range.utility.helpers]
The following is to be added to the Index of library concepts
[concept.different]
,
[concept.similar]
,
[concept.distinct]