D.2 Non-local use of TU-local entities [depr.local]
D.6 Implicit declaration of copy functions [depr.impldec]
D.8 Literal operator function declarations using an identifier [depr.lit]
This Annex describes features of this document
that are specified for compatibility with existing implementations
.These are deprecated features, where
deprecated
is defined as:
Normative for the current revision of C++,
but having been identified as a candidate for removal from future revisions
.An implementation may declare library names and entities described in this Clause with the
deprecated attribute.A declaration of a non-TU-local entity that is an exposure (
[basic.link])
is deprecated
.[
Note 1: 
Such a declaration in an importable module unit is ill-formed
. — 
end note]
[
Example 1: 
namespace {
  struct A {
    void f() {}
  };
}
A h();                          
inline void g() {A().f();}      
 — 
end example]
 [
Example 1: 
struct X {
  int x;
  void foo(int n) {
    auto f = [=]() { x = n; };          
    auto g = [=, this]() { x = n; };    
  }
};
 — 
end example]
 Postfix 
++ and 
-- expressions (
[expr.post.incr]) and
prefix 
++ and 
-- expressions (
[expr.pre.incr])
of volatile-qualified arithmetic and pointer types are deprecated
.[
Example 1: 
volatile int velociraptor;
++velociraptor;                     
 — 
end example]
Certain assignments
where the left operand is a volatile-qualified non-class type
are deprecated; see 
[expr.assign].[
Example 2: 
int neck, tail;
volatile int brachiosaur;
brachiosaur = neck;                 
tail = brachiosaur;                 
tail = brachiosaur = neck;          
brachiosaur += neck;                
 — 
end example]
A function type (
[dcl.fct])
with a parameter with volatile-qualified type or
with a volatile-qualified return type is deprecated
.[
Example 3: 
volatile struct amber jurassic();                               
void trex(volatile short left_arm, volatile short right_arm);   
void fly(volatile struct pterosaur* pteranodon);                
 — 
end example]
[
Example 4: 
struct linhenykus { short forelimb; };
void park(linhenykus alvarezsauroid) {
  volatile auto [what_is_this] = alvarezsauroid;                
  
}
 — 
end example]
 [
Example 1: 
void f(int...);         
void g(auto...);        
void h(auto......);     
 — 
end example]
 The implicit definition of a 
copy constructor
as defaulted is deprecated if the class has
a user-declared copy assignment operator or
a user-declared 
destructor.The implicit definition of a 
copy assignment operator
as defaulted is deprecated if the class has
a user-declared copy constructor or
a user-declared destructor
.It is possible that future versions of C++ will specify
that these implicit definitions are deleted (
[dcl.fct.def.delete])
.For compatibility with prior revisions of C++, a 
constexpr
static data member may be redundantly redeclared outside the class with no
initializer (
[basic.def], 
[class.static.data])
.This usage is deprecated
.[
Example 1: 
struct A {
  static constexpr int n = 5;   
};
constexpr int A::n;             
 — 
end example]
D.8 Literal operator function declarations using an identifier [depr.lit]
The use of the keyword 
template
before the qualified name of a class or alias template
without a template argument list is deprecated (
[temp.names])
.The following members are defined
in addition to those specified in 
[numeric.limits.general]:
static constexpr float_denorm_style has_denorm = denorm_absent;
static constexpr bool has_denorm_loss = false;
The values of 
has_denorm and 
has_denorm_loss of
specializations of 
numeric_limits are unspecified
.The following members of the specialization 
numeric_limits<bool> are defined
in addition to those specified in 
[numeric.special]:
static constexpr float_denorm_style has_denorm = denorm_absent;
static constexpr bool has_denorm_loss = false;
The header 
 has the following macros:
#define FLT_HAS_SUBNORM see below
#define DBL_HAS_SUBNORM see below
#define LDBL_HAS_SUBNORM see below
#define DECIMAL_DIG see below
The header defines these macros the same as
the C standard library header 
.See also: ISO/IEC 9899:2024, 5.2.4.2.2, 7.33.5
In addition to being available via inclusion of the 
 header,
the macros 
INFINITY and 
NAN are
available when 
 is included
.See also: ISO/IEC 9899:2024, 7.12
The header 
 has the following macro:
#define __bool_true_false_are_defined 1
See also: ISO/IEC 9899:2024, 7.19
The header 
 has the following additional macros:
#define ENODATA see below
#define ENOSR see below
#define ENOSTR see below
#define ETIME see below
The meaning of these macros is defined by the POSIX standard
.The following 
enum errc enumerators are defined
in addition to those specified in 
[system.error.syn]:
The value of each 
enum errc enumerator above
is the same as the value of the 
 macro
shown in the above synopsis
.template<class T> struct is_trivial;
template<class T> struct is_pod;
template<size_t Len, size_t Align = default-alignment>
  struct aligned_storage;
template<size_t Len, class... Types>
  struct aligned_union;
The header 
 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&);
}
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);
Preconditions: 
T meets the 
Cpp17EqualityComparable requirements (Table 
28)
. template<class T> bool operator>(const T& x, const T& y);
Preconditions: 
T meets the 
Cpp17LessThanComparable requirements (Table 
29)
. template<class T> bool operator<=(const T& x, const T& y);
Preconditions: 
T meets the 
Cpp17LessThanComparable requirements (Table 
29)
. template<class T> bool operator>=(const T& x, const T& y);
Preconditions: 
T meets the 
Cpp17LessThanComparable requirements (Table 
29)
. The header 
 has the following additions:
namespace std {
  template<class T> struct tuple_size<volatile T>;
  template<class T> struct tuple_size<const volatile T>;
  template<size_t I, class T> struct tuple_element<I, volatile T>;
  template<size_t I, class T> struct tuple_element<I, const volatile T>;
}
template<class T> struct tuple_size<volatile T>;
template<class T> struct tuple_size<const volatile T>;
Let 
TS denote 
tuple_size<T> of the cv-unqualified type 
T.If the expression 
TS::value is well-formed
when treated as an 
unevaluated operand,
then specializations of each of the two templates meet
the 
Cpp17TransformationTrait requirements with a base characteristic of
integral_constant<size_t, TS::value>.Otherwise, they have no member 
value.Access checking is performed as if
in a context unrelated to 
TS and 
T.Only the validity of the immediate context of the expression is considered
.In addition to being available via inclusion of the 
 header,
the two templates are available when any of the headers
,
, or
are included
.template<size_t I, class T> struct tuple_element<I, volatile T>;
template<size_t I, class T> struct tuple_element<I, const volatile T>;
Let 
TE denote 
tuple_element_t<I, T>
of the cv-unqualified type 
T.Then specializations of each of the two templates meet
the 
Cpp17TransformationTrait requirements
with a member typedef 
type that names the following type:
- for the first specialization, add_volatile_t<TE>, and
- for the second specialization, add_cv_t<TE>.
In addition to being available via inclusion of the 
 header,
the two templates are available when any of the headers
,
, or
are included
.The header 
 has the following additions:
namespace std {
  template<class T> struct variant_size<volatile T>;
  template<class T> struct variant_size<const volatile T>;
  template<size_t I, class T> struct variant_alternative<I, volatile T>;
  template<size_t I, class T> struct variant_alternative<I, const volatile T>;
}
template<class T> struct variant_size<volatile T>;
template<class T> struct variant_size<const volatile T>;
Let 
VS denote 
variant_size<T>
of the cv-unqualified type 
T.Then specializations of each of the two templates meet
the 
Cpp17UnaryTypeTrait requirements
with a base characteristic of 
integral_constant<size_t, VS::value>.template<size_t I, class T> struct variant_alternative<I, volatile T>;
template<size_t I, class T> struct variant_alternative<I, const volatile T>;
Let 
VA denote 
variant_alternative<I, T>
of the cv-unqualified type 
T.Then specializations of each of the two templates meet
the 
Cpp17TransformationTrait requirements
with a member typedef 
type that names the following type:
- for the first specialization, add_volatile_t<VA::type>, and
- for the second specialization, add_cv_t<VA::type>.
The header 
 has the following addition:
namespace std {
  template<class Category, class T, class Distance = ptrdiff_t,
           class Pointer = T*, class Reference = T&>
  struct iterator {
    using iterator_category = Category;
    using value_type        = T;
    using difference_type   = Distance;
    using pointer           = Pointer;
    using reference         = Reference;
  };
}
The
iterator
template may be used as a base class to ease the definition of required types
for new iterators
.[
Note 1: 
If the new iterator type is a class template, then these aliases
will not be visible from within the iterator class's template definition, but
only to callers of that class
. — 
end note]
[
Example 1: 
If a C++ program wants to define a bidirectional iterator for some data
structure containing double and such that it works on a large memory
model of the implementation, it can do so with:
class MyIterator :
  public iterator<bidirectional_iterator_tag, double, long, T*, T&> {
  
};
 — 
end example]
The following member is declared in addition to those members
specified in 
[move.iter.elem]:
namespace std {
  template<class Iterator>
  class move_iterator {
  public:
    constexpr pointer operator->() const;
  };
}
constexpr pointer operator->() const;
The 
ctype locale category includes the following facets
as if they were specified
in Table 
91 of 
[locale.category].codecvt<char16_t, char, mbstate_t>
codecvt<char32_t, char, mbstate_t>
codecvt<char16_t, char8_t, mbstate_t>
codecvt<char32_t, char8_t, mbstate_t>
The 
ctype locale category includes the following facets
as if they were specified
in Table 
92 of 
[locale.category].codecvt_byname<char16_t, char, mbstate_t>
codecvt_byname<char32_t, char, mbstate_t>
codecvt_byname<char16_t, char8_t, mbstate_t>
codecvt_byname<char32_t, char8_t, mbstate_t>
The following class template specializations are required
in addition to those specified in 
[locale.codecvt].The specializations 
codecvt<char16_t, char, mbstate_t> and
codecvt<char16_t, char8_t, mbstate_t>
convert between the UTF-16 and UTF-8 encoding forms, and
the specializations 
codecvt<char32_t, char, mbstate_t> and
codecvt<char32_t, char8_t, mbstate_t>
convert between the UTF-32 and UTF-8 encoding forms
.The header 
 has the following additions:
char* asctime(const tm* timeptr);
char* ctime(const time_t* timer);
See also: ISO/IEC 9899:2024, 7.29
The header 
 has the following additions:
template<class Source>
  path u8path(const Source& source);
template<class InputIterator>
  path u8path(InputIterator first, InputIterator last);
Mandates: The value type of 
Source and 
InputIterator is
char or 
char8_t. Preconditions: The 
source and [
first, last) sequences are UTF-8 encoded
.  Returns: 
- If path::value_type is char and the current native
      narrow encoding ([fs.path.type.cvt]) is UTF-8,
      return path(source) or path(first, last);
      otherwise,
- if path::value_type is wchar_t and the
      native wide encoding is UTF-16, or
      if path::value_type is char16_t or char32_t,
      convert source or [first, last)
      to a temporary, tmp, of type path::string_type and
      return path(tmp);
      otherwise,
- convert source or [first, last)
      to a temporary, tmp, of type u32string and
      return path(tmp).
 Remarks: Argument format conversion (
[fs.path.fmt.cvt]) applies to the
  arguments for these functions
.  How Unicode encoding conversions are performed is
  unspecified
.[
Example 1: 
A string is to be read from a database that is encoded in UTF-8, and used
    to create a directory using the native encoding for filenames:
namespace fs = std::filesystem;
std::string utf8_string = read_utf8_data();
fs::create_directory(fs::u8path(utf8_string));
For POSIX-based operating systems with the native narrow encoding set
    to UTF-8, no encoding or type conversion occurs
.For POSIX-based operating systems with the native narrow encoding not
    set to UTF-8, a conversion to UTF-32 occurs, followed by a conversion to the
    current native narrow encoding
.Some Unicode characters may have no native character
    set representation
.For Windows-based operating systems a conversion from UTF-8 to
    UTF-16 occurs
. — 
end example]
[
Note 1: 
The example above is representative of
a historical use of 
filesystem::u8path.To indicate a UTF-8 encoding,
passing a 
std::u8string to 
path's constructor is preferred
as it is consistent with 
path's handling of other encodings
. — 
end note]
The following members are declared in addition to those members
specified in 
[fs.path.member]:
namespace std::filesystem {
  class path {
  public:
    std::string string() const;
    std::string generic_string() const;
  };
}
std::string string() const;
Returns: 
system_encoded_string(). std::string generic_string() const;
Returns: 
generic_system_encoded_string(). The header 
 has the following additions
.If an 
atomic (
[atomics.types.generic]) specialization has one of the following overloads,
then that overload participates in overload resolution
even if 
atomic<T>::is_always_lock_free is 
false:
void store(T desired, memory_order order = memory_order::seq_cst) volatile noexcept;
T operator=(T desired) volatile noexcept;
T load(memory_order order = memory_order::seq_cst) const volatile noexcept;
operator T() const volatile noexcept;
T exchange(T desired, memory_order order = memory_order::seq_cst) volatile noexcept;
bool compare_exchange_weak(T& expected, T desired,
                           memory_order success, memory_order failure) volatile noexcept;
bool compare_exchange_strong(T& expected, T desired,
                             memory_order success, memory_order failure) volatile noexcept;
bool compare_exchange_weak(T& expected, T desired,
                           memory_order order = memory_order::seq_cst) volatile noexcept;
bool compare_exchange_strong(T& expected, T desired,
                             memory_order order = memory_order::seq_cst) volatile noexcept;
T fetch_key(T operand, memory_order order = memory_order::seq_cst) volatile noexcept;
T operator op=(T operand) volatile noexcept;
T* fetch_key(ptrdiff_t operand, memory_order order = memory_order::seq_cst) volatile noexcept;
template<class T>
  void atomic_init(volatile atomic<T>* object, typename atomic<T>::value_type desired) noexcept;
template<class T>
  void atomic_init(atomic<T>* object, typename atomic<T>::value_type desired) noexcept;
Effects: Equivalent to: atomic_store_explicit(object, desired, memory_order::relaxed);
#define ATOMIC_VAR_INIT(value) see below
The macro expands to a token sequence suitable for constant initialization of
an atomic variable with static storage duration of a type that
is initialization-compatible with 
value.[
Note 1: 
This operation possibly needs to initialize locks
. — 
end note]
Concurrent access to the variable being initialized,
even via an atomic operation,
constitutes a data race
.[
Example 1: 
atomic<int> v = ATOMIC_VAR_INIT(5);
 — 
end example]
The memory_order enumeration contains an additional enumerator:
consume = 1
 
The 
memory_order::consume enumerator is allowed wherever
memory_order::acquire is allowed, and it has the same meaning
.template<class T> constexpr T kill_dependency(T y) noexcept;