Expression  Return type  Requirement 
a == b  convertible to bool  == is an equivalence relation,
that is, it has the following properties:

Expression  Return type  Requirement 
a < b  convertible to bool  < is a strict weak ordering relation ([alg.sorting]) 
Expression  Postcondition 
T t;  object t is defaultinitialized 
T u{};  object u is valueinitialized or aggregateinitialized 
T() T{}  an object of type T is valueinitialized
or aggregateinitialized 
Expression  Postcondition 
T u = rv;  u is equivalent to the value of rv before the construction 
T(rv)  T(rv) is equivalent to the value of rv before the construction 
rv's state is unspecified
[ Note : rv must still meet the requirements of the library
component that is using it. The operations listed in those requirements must
work as specified whether rv has been moved from or not. — end note ] 
Expression  Postcondition 
T u = v;  the value of v is unchanged and is equivalent to u 
T(v)  the value of v is unchanged and is equivalent to T(v) 
Expression  Return type  Return value  Postcondition 
t = rv  T&  t  If t and rv do not refer to the same object,
t is equivalent to the value of rv before the assignment 
rv's state is unspecified. 
Expression  Return type  Return value  Postcondition 
t = v  T&  t  t is equivalent to v, the value of v is unchanged 
#include <utility> // Requires: std::forward<T>(t) shall be swappable with std::forward<U>(u). template<class T, class U> void value_swap(T&& t, U&& u) { using std::swap; swap(std::forward<T>(t), std::forward<U>(u)); // OK: uses “swappable with” conditions // for rvalues and lvalues } // Requires: lvalues of T shall be swappable. template<class T> void lv_swap(T& t1, T& t2) { using std::swap; swap(t1, t2); // OK: uses swappable conditions for lvalues of type T } namespace N { struct A { int m; }; struct Proxy { A* a; }; Proxy proxy(A& a) { return Proxy{ &a }; } void swap(A& x, Proxy p) { std::swap(x.m, p.a>m); // OK: uses context equivalent to swappable // conditions for fundamental types } void swap(Proxy p, A& x) { swap(x, p); } // satisfy symmetry constraint } int main() { int i = 1, j = 2; lv_swap(i, j); assert(i == 2 && j == 1); N::A a1 = { 5 }, a2 = { 5 }; value_swap(a1, proxy(a2)); assert(a1.m == 5 && a2.m == 5); }
Expression  Return type  Operational semantics 
P u(np);  Postconditions: u == nullptr  
P u = np;  
P(np)  Postconditions: P(np) == nullptr  
t = np  P&  Postconditions: t == nullptr 
a != b  contextually convertible to bool  !(a == b) 
a == np  contextually convertible to bool  a == P() 
np == a  
a != np  contextually convertible to bool  !(a == np) 
np != a 
Expression  Return type  Requirement 
h(k)  size_t  The value returned shall depend only on the argument k for the duration of
the program. 
h(u)  size_t  Shall not modify u. 
Variable  Definition 
T, U, C  any cvunqualified object type ([basic.types]) 
X  an allocator class for type T 
Y  the corresponding allocator class for type U 
XX  the type allocator_traits<X> 
YY  the type allocator_traits<Y> 
a, a1, a2  lvalues of type X 
u  the name of a variable being declared 
b  a value of type Y 
c  a pointer of type C* through which indirection is valid 
p  a value of type XX::pointer, obtained
by calling a1.allocate, where a1 == a 
q  
r  
w  a value of type XX::void_pointer obtained by
conversion from a value p 
x  a value of type XX::const_void_pointer obtained by
conversion from a value q or a value w 
y  a value of type XX::const_void_pointer obtained by
conversion from a result value of YY::allocate, or else a value of
type (possibly const) std::nullptr_t. 
n  a value of type XX::size_type. 
Args  a template parameter pack 
args  a function parameter pack with the pattern Args&& 
Expression  Return type  Assertion/note  Default 
pre/postcondition  
X::pointer  T*  
X::const_pointer  X::pointer is convertible to X::const_pointer  pointer_traits<X::pointer>::rebind<const T>  
X::void_pointer Y::void_pointer  pointer_traits<X::pointer>::rebind<void>  
X::const_void_pointer Y::const_void_pointer  X::pointer, X::const_pointer, and X::void_pointer are convertible to X::const_void_pointer.  pointer_traits<X::pointer>::rebind<const void>  
X::value_type  Identical to T  
X::size_type  unsigned integer type  a type that can represent the size of the largest object in the allocation model.  make_unsigned_t<X::difference_type> 
X::difference_type  signed integer type  a type that can represent the difference between any two pointers
in the allocation model.  pointer_traits<X::pointer>::difference_type 
typename X::template rebind<U>::other  Y  See Note A, below.  
*p  T&  
*q  const T&  *q refers to the same object as *p  
p>m  type of T::m  equivalent to (*p).m  
q>m  type of T::m  equivalent to (*q).m  
static_cast<X::pointer>(w)  X::pointer  static_cast<X::pointer>(w) == p  
static_cast<X::const_pointer>(x)  X::const_pointer  static_cast< X::const_pointer>(x) == q  
pointer_traits<X::pointer>::pointer_to(r)  X::pointer  same as p  
a.allocate(n)  X::pointer  
a.allocate(n, y)  X::pointer  Same as a.allocate(n). The use of y is unspecified, but
it is intended as an aid to locality.  a.allocate(n) 
a.deallocate(p,n)  (not used)  Requires: p shall be a value returned by an earlier call
to allocate that has not been invalidated by
an intervening call to deallocate.  
a.max_size()  X::size_type  the largest value that can meaningfully be passed to X::allocate()  numeric_limits<size_type>::max() / sizeof(value_type) 
a1 == a2  bool  returns true only if storage allocated from each can
be deallocated via the other. operator== shall be reflexive, symmetric,
and transitive, and shall not exit via an exception.  
a1 != a2  bool  same as !(a1 == a2)  
a == b  bool  same as a == Y::rebind<T>::other(b)  
a != b  bool  same as !(a == b)  
X u(a); X u = a;  Shall not exit via an exception. Postconditions: u == a  
X u(b);  Shall not exit via an exception. Postconditions: Y(u) == b, u == X(b)  
X u(std::move(a)); X u = std::move(a);  Shall not exit via an exception.  
X u(std::move(b));  Shall not exit via an exception.  
a.construct(c, args)  (not used)  Effects: Constructs an object of type C at
c  ::new ((void*)c) C(forward<Args>(args)...) 
a.destroy(c)  (not used)  Effects: Destroys the object at c  c>~C() 
a.select_on_container_copy_construction()  X  Typically returns either a or X()  return a; 
X::propagate_on_container_copy_assignment  Identical to or derived from true_type or false_type  true_type only if an allocator of type X should be copied
when the client container is copyassigned. See Note B, below.  false_type 
X::propagate_on_container_move_assignment  Identical to or derived from true_type or false_type  true_type only if an allocator of type X should be moved
when the client container is moveassigned. See Note B, below.  false_type 
X::propagate_on_ container_swap  Identical to or derived from true_type or false_type  See Note B, below.  false_type 
X::is_always_equal  Identical to or derived from true_type or false_type  true_type only if the expression a1 == a2 is guaranteed
to be true for any two (possibly const) values
a1, a2 of type X.  is_empty<X>::type 
addressof(*(a + n)) == addressof(*a) + nis true.
w1 == w2 w1 != w2either or both objects may be replaced by an equivalentlyvalued object of type X::const_void_pointer with no change in semantics.
p1 == p2 p1 != p2 p1 < p2 p1 <= p2 p1 >= p2 p1 > p2 p1  p2either or both objects may be replaced by an equivalentlyvalued object of type X::const_pointer with no change in semantics.
template<class Tp> struct SimpleAllocator { typedef Tp value_type; SimpleAllocator(ctor args); template<class T> SimpleAllocator(const SimpleAllocator<T>& other); [[nodiscard]] Tp* allocate(std::size_t n); void deallocate(Tp* p, std::size_t n); }; template<class T, class U> bool operator==(const SimpleAllocator<T>&, const SimpleAllocator<U>&); template<class T, class U> bool operator!=(const SimpleAllocator<T>&, const SimpleAllocator<U>&);— end example