template< class T >
struct atomic;
template< class U >
struct atomic<U*>;
#define _Atomic(T) /* see below */
(5) (since C++23)Each instantiation and full specialization of the std::atomic
template defines an atomic type. If one thread writes to an atomic object while another thread reads from it, the behavior is well-defined (see memory model for details on data races).
In addition, accesses to atomic objects may establish inter-thread synchronization and order non-atomic memory accesses as specified by std::memory_order.
std::atomic
is neither copyable nor movable.
The compatibility macro _Atomic
is provided in <stdatomic.h> such that _Atomic(T)
is identical to std::atomic<T>
while both are well-formed.
It is unspecified whether any declaration in namespace std
is available when <stdatomic.h> is included.
The primary std::atomic
template may be instantiated with any TriviallyCopyable type T
satisfying both CopyConstructible and CopyAssignable. The program is ill-formed if any of following values is false:
struct Counters { int a; int b; }; // user-defined trivially-copyable type std::atomic<Counters> cnt; // specialization for the user-defined type
std::atomic<bool> uses the primary template. It is guaranteed to be a standard layout struct and has a trivial destructor.
[edit] Partial specializationsThe standard library provides partial specializations of the std::atomic
template for the following types with additional properties that the primary template does not have:
Partial specializations
std::atomic<U*>
for all pointer types. These specializations have standard layout
, trivial default constructors,(until C++20)and trivial destructors. Besides the operations provided for all atomic types, these specializations additionally support atomic arithmetic operations appropriate to pointer types, such as
fetch_add
,
fetch_sub
.
[edit] Specializations for integral typesWhen instantiated with one of the following integral types, std::atomic
provides additional atomic operations appropriate to integral types such as fetch_add
, fetch_sub
, fetch_and
, fetch_or
, fetch_xor
:
Additionally, the resulting std::atomic<Integral>
specialization has standard layout, a trivial default constructor,(until C++20) and a trivial destructor. Signed integer arithmetic is defined to use two's complement; there are no undefined results.
When instantiated with one of the cv-unqualified floating-point types (float, double, long double and cv-unqualified extended floating-point types(since C++23)), std::atomic
provides additional atomic operations appropriate to floating-point types such as fetch_add
and fetch_sub
.
Additionally, the resulting std::atomic<Floating>
specialization has standard layout and a trivial destructor.
No operations result in undefined behavior even if the result is not representable in the floating-point type. The floating-point environment in effect may be different from the calling thread's floating-point environment.
(since C++20) [edit] Member types Type Definitionvalue_type
T
(regardless of whether specialized or not) difference_type
[1]
value_type
(only for atomic<Integral>
and atomic<Floating>
(since C++20) specializations)
std::ptrdiff_t (only for std::atomic<U*>
specializations)
difference_type
is not defined in the primary std::atomic
template or in the partial specializations for std::shared_ptr and std::weak_ptr.Type aliases are provided for bool and all integral types listed above, as follows:
Note:
std::atomic_intN_t
,
std::atomic_uintN_t
,
std::atomic_intptr_t
, and
std::atomic_uintptr_t
are defined if and only if
std::intN_t
,
std::uintN_t
,
std::intptr_t, and
std::uintptr_tare defined, respectively.
std::atomic_signed_lock_free
and std::atomic_unsigned_lock_free
are optional in freestanding implementations.
There are non-member function template equivalents for all member functions of std::atomic
. Those non-member functions may be additionally overloaded for types that are not specializations of std::atomic
, but are able to guarantee atomicity. The only such type in the standard library is std::shared_ptr<U>.
_Atomic
is a keyword and used to provide atomic types in C.
Implementations are recommended to ensure that the representation of _Atomic(T)
in C is same as that of std::atomic<T>
in C++ for every possible type T
. The mechanisms used to ensure atomicity and memory ordering should be compatible.
On GCC and Clang, some of the functionality described here requires linking against -latomic
.
#include <atomic> #include <iostream> #include <thread> #include <vector> std::atomic_int acnt; int cnt; void f() { for (auto n{10000}; n; --n) { ++acnt; ++cnt; // Note: for this example, relaxed memory order is sufficient, // e.g. acnt.fetch_add(1, std::memory_order_relaxed); } } int main() { { std::vector<std::jthread> pool; for (int n = 0; n < 10; ++n) pool.emplace_back(f); } std::cout << "The atomic counter is " << acnt << '\n' << "The non-atomic counter is " << cnt << '\n'; }
Possible output:
The atomic counter is 100000 The non-atomic counter is 69696[edit] 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 2441 C++11 typedefs for atomic versions of optionalstd::atomic<T>
was permitted for any T
T
was questionable disallow T
being cv-qualified P0558R1 C++11 template argument deduction for some
value_type
difference_type
are added [edit] See also
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4