is-integer-like , is-signed-integer-like
template
<
class
T
>
constexpr bool /*is-integer-like*/ = /* see description */ ; |
(1) |
(since C++20)
( exposition only* ) |
template
<
class
T
>
constexpr bool /*is-signed-integer-like*/ = /* see description */ ; |
(2) |
(since C++20)
( exposition only* ) |
T
is an integer-like type.
T
is a signed-integer-like type.
Integer-class type
A type
T
is an
integer-class type
if it is in a set of implementation-defined types that behave as
integer types
do, as defined
below
. An integer-class type is not necessarily a
class type
.
An integer-class type can represent 2 N consecutive integers, where N , a positive integer, is called the width of the integer-class type.
An integer-class type is either signed or unsigned:
-
A
signed integer class type
can represent all integers in
[
-2 N-1,
2 N-1 -1]
, where N is greater than the width of every signed integral type. -
An
unsigned integer class type
can represent all integers in
[
0,
2 N -1]
, where N is greater than the width of every unsigned integral type.
All integer-class types model
regular
and
three_way_comparable
<
std::
strong_ordering
>
.
A value-initialized object of integer-class type has value â 0 â .
An expression
E
of integer-class type
T
is
contextually convertible
to
bool
as if by
bool
(
E
!
=
T
(
0
)
)
.
Integer-like type
A type other than (possibly cv-qualified)
bool
is
integer-like
if it models
integral
or if it is an integer-class type.
-
An integer-like type is
signed-integer-like
if it models
signed_integral
or if it is a signed-integer-class type. -
An integer-like type is
unsigned-integer-like
if it models
unsigned_integral
or if it is an unsigned-integer-class type.
Required behaviors
Expressions of integer-class type are explicitly convertible to any integer-like type, and implicitly convertible to any integer-class type of equal or greater width and the same signedness. Expressions of integral type are both implicitly and explicitly convertible to any integer-class type. Conversions between integral and integer-class types and between two integer-class types do not exit via an exception. The result of such a conversion is the unique value of the destination type that is congruent to the source modulo 2 N , where N is the width of the destination type.
Let
Int<T>
denote the following type:
-
If
T
is an integer-class type,Int<T>
is a unique hypothetical extended integer type of the same signedness with the same width asT
. -
If
T
is an integral type, letInt<T>
is the same type asT
.
Given the following types, values and operators:
Type | Definition |
IC
|
an integer-class type |
IL
|
an integer-like type |
Value | Definition |
a |
an object of type
IC
|
b |
an object of type
IL
|
c | an lvalue of an integeral type |
x |
an object of type
Int<IC>
that represent the same value as
a
|
y |
an object of type
Int<IL>
that represent the same value as
b
|
Operator | Definition |
@ = | one of + = , - = , * = , / = , % = , & = , | = , ^ = , <<= and >>= |
@ | one of + , - , * , / , % , & , | , ^ , << , >> , && , || , == , ! = , < , > , <= , >= , <=> and , |
The following expressions must be well-formed and have their specified result and effects if the specified conditions are satisfied:
Expression | Condition | Result | Effects |
---|---|---|---|
a ++ | No condition |
a prvalue of type
IC
whose value is equal to that of
a
prior to the evaluation
|
modifies the value of a by adding 1 to it |
a -- | modifies the value of a by subtracting 1 to it | ||
++ a | expression-equivalent to a + = 1 | ||
-- a | expression-equivalent to a - = 1 | ||
& a | expression-equivalent to std:: addressof ( a ) | ||
! a | ! x is well-formed | same as ! x | |
+ a | + x is well-formed |
same as
+
x
, but has type
IC
|
same as + x |
- a | - x is well-formed |
same as
-
x
, but has type
IC
|
same as - x |
~a | ~x is well-formed |
same as
~x
, but has type
IC
|
same as ~x |
c @ = a | c @ = x is well-formed | an lvalue referring to c | same as c @ = x |
a @ = b | x @ = y is well-formed | an lvalue referring to a | same as x @ = y , except that the value that would be stored into x is stored into a |
a @ b | x @ y is well-formed |
same as
x @ y
, but the result type is different:
|
same as x @ y |
b @ a | y @ x is well-formed |
same as
y @ x
, but the result type is different:
|
same as y @ x |
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 3366
( P2393R1 ) |
C++20 |
the conversion between an integer-class type and its corresponding
integer type was not guaranteed to produce a representable value |
guaranteed |
LWG 3376
( P2393R1 ) |
C++20 | integer-class types could only be class types |
also allowed
non-class types |
LWG 3467 | C++20 | bool was considered as an integer-like type | excluded |
LWG 3575
( P2393R1 ) |
C++20 | integer-class types were not guaranteed to be three-way-comparable | guaranteed |
See also
(C++20)
|
specifies that a
semiregular
type can be incremented with pre- and post-increment operators
(concept) |