|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Member functions | ||||
(C++20) | ||||
(C++20) | ||||
(C++20) | ||||
| Constants | ||||
(C++17) | ||||
| Specialized member functions | ||||
| Specialized for integral, floating-point(C++20) and pointer types | ||||
| Specialized for integral and pointer types only | ||||
(C++26) | ||||
(C++26) | ||||
| Specialized for integral types only | ||||
Defined in header <atomic> | ||
template<class T> struct atomic; | (1) | (since C++11) |
template<class U> struct atomic<U*>; | (2) | (since C++11) |
Defined in header <memory> | ||
template<class U> struct atomic<std::shared_ptr<U>>; | (3) | (since C++20) |
template<class U> struct atomic<std::weak_ptr<U>>; | (4) | (since C++20) |
Defined in header <stdatomic.h> | ||
#define _Atomic(T) /* see below */ | (5) | (since C++23) |
Each instantiation and full specialization of thestd::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 (seememory 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 bystd::memory_order.
std::atomic is neither copyable nor movable.
The compatibility macro It is unspecified whether any declaration in namespace | (since C++23) |
Contents |
The primarystd::atomic template may be instantiated with anyTriviallyCopyable typeT satisfying bothCopyConstructible andCopyAssignable. The program is ill-formed if any of following values isfalse:
struct Counters{int a;int b;};// user-defined trivially-copyable typestd::atomic<Counters> cnt;// specialization for the user-defined type
std::atomic<bool> uses the primary template. It is guaranteed to be astandard layout struct and has atrivial destructor.
The standard library provides partial specializations of thestd::atomic template for the following types with additional properties that the primary template does not have:
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 asfetch_add,fetch_sub.3,4) Partial specializationsstd::atomic<std::shared_ptr<U>> andstd::atomic<std::weak_ptr<U>> are provided forstd::shared_ptr andstd::weak_ptr. Seestd::atomic<std::shared_ptr> andstd::atomic<std::weak_ptr> for details. | (since C++20) |
When instantiated with one of the following integral types,std::atomic provides additional atomic operations appropriate to integral types such asfetch_add,fetch_sub,fetch_and,fetch_or,fetch_xor:
Additionally, the resultingstd::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.
Specializations for floating-point typesWhen instantiated with one of the cv-unqualified floating-point types (float,double,longdouble and cv-unqualifiedextended floating-point types(since C++23)), Additionally, the resulting No operations result in undefined behavior even if the result is not representable in the floating-point type. Thefloating-point environment in effect may be different from the calling thread's floating-point environment. | (since C++20) |
| Type | Definition | ||||
value_type | T(regardless of whether specialized or not) | ||||
difference_type[1] |
|
difference_type is not defined in the primarystd::atomic template or in the partial specializations forstd::shared_ptr andstd::weak_ptr.| constructs an atomic object (public member function)[edit] | |
| stores a value into an atomic object (public member function)[edit] | |
| checks if the atomic object is lock-free (public member function)[edit] | |
| atomically replaces the value of the atomic object with a non-atomic argument (public member function)[edit] | |
| atomically obtains the value of the atomic object (public member function)[edit] | |
| loads a value from an atomic object (public member function)[edit] | |
| atomically replaces the value of the atomic object and obtains the value held previously (public member function)[edit] | |
| atomically compares the value of the atomic object with non-atomic argument and performs atomic exchange if equal or atomic load if not (public member function)[edit] | |
(C++20) | blocks the thread until notified and the atomic value changes (public member function)[edit] |
(C++20) | notifies at least one thread waiting on the atomic object (public member function)[edit] |
(C++20) | notifies all threads blocked waiting on the atomic object (public member function)[edit] |
Constants | |
[static](C++17) | indicates that the type is always lock-free (public static member constant)[edit] |
Specialized for integral, floating-point(since C++20) and pointer types | |
| atomically adds the argument to the value stored in the atomic object and obtains the value held previously (public member function)[edit] | |
| atomically subtracts the argument from the value stored in the atomic object and obtains the value held previously (public member function)[edit] | |
| adds to or subtracts from the atomic value (public member function)[edit] | |
Specialized for integral and pointer types only | |
(C++26) | atomically performsstd::max between the argument and the value of the atomic object and obtains the value held previously (public member function)[edit] |
(C++26) | atomically performsstd::min between the argument and the value of the atomic object and obtains the value held previously (public member function)[edit] |
| increments or decrements the atomic value by one (public member function)[edit] | |
Specialized for integral types only | |
| atomically performs bitwise AND between the argument and the value of the atomic object and obtains the value held previously (public member function)[edit] | |
| atomically performs bitwise OR between the argument and the value of the atomic object and obtains the value held previously (public member function)[edit] | |
| atomically performs bitwise XOR between the argument and the value of the atomic object and obtains the value held previously (public member function)[edit] | |
| performs bitwise AND, OR, XOR with the atomic value (public member function)[edit] | |
Type aliases are provided forbool and all integral types listed above, as follows:
Aliases for all | |
atomic_bool (C++11) | std::atomic<bool> (typedef)[edit] |
atomic_char (C++11) | std::atomic<char> (typedef)[edit] |
atomic_schar (C++11) | std::atomic<signedchar> (typedef)[edit] |
atomic_uchar (C++11) | std::atomic<unsignedchar> (typedef)[edit] |
atomic_short (C++11) | std::atomic<short> (typedef)[edit] |
atomic_ushort (C++11) | std::atomic<unsignedshort> (typedef)[edit] |
atomic_int (C++11) | std::atomic<int> (typedef)[edit] |
atomic_uint (C++11) | std::atomic<unsignedint> (typedef)[edit] |
atomic_long (C++11) | std::atomic<long> (typedef)[edit] |
atomic_ulong (C++11) | std::atomic<unsignedlong> (typedef)[edit] |
atomic_llong (C++11) | std::atomic<longlong> (typedef)[edit] |
atomic_ullong (C++11) | std::atomic<unsignedlonglong> (typedef)[edit] |
atomic_char8_t (C++20) | std::atomic<char8_t> (typedef)[edit] |
atomic_char16_t (C++11) | std::atomic<char16_t> (typedef)[edit] |
atomic_char32_t (C++11) | std::atomic<char32_t> (typedef)[edit] |
atomic_wchar_t (C++11) | std::atomic<wchar_t> (typedef)[edit] |
atomic_int8_t (C++11)(optional) | std::atomic<std::int8_t> (typedef)[edit] |
atomic_uint8_t (C++11)(optional) | std::atomic<std::uint8_t> (typedef)[edit] |
atomic_int16_t (C++11)(optional) | std::atomic<std::int16_t> (typedef)[edit] |
atomic_uint16_t (C++11)(optional) | std::atomic<std::uint16_t> (typedef)[edit] |
atomic_int32_t (C++11)(optional) | std::atomic<std::int32_t> (typedef)[edit] |
atomic_uint32_t (C++11)(optional) | std::atomic<std::uint32_t> (typedef)[edit] |
atomic_int64_t (C++11)(optional) | std::atomic<std::int64_t> (typedef)[edit] |
atomic_uint64_t (C++11)(optional) | std::atomic<std::uint64_t> (typedef)[edit] |
atomic_int_least8_t (C++11) | std::atomic<std::int_least8_t> (typedef)[edit] |
atomic_uint_least8_t (C++11) | std::atomic<std::uint_least8_t> (typedef)[edit] |
atomic_int_least16_t (C++11) | std::atomic<std::int_least16_t> (typedef)[edit] |
atomic_uint_least16_t (C++11) | std::atomic<std::uint_least16_t> (typedef)[edit] |
atomic_int_least32_t (C++11) | std::atomic<std::int_least32_t> (typedef)[edit] |
atomic_uint_least32_t (C++11) | std::atomic<std::uint_least32_t> (typedef)[edit] |
atomic_int_least64_t (C++11) | std::atomic<std::int_least64_t> (typedef)[edit] |
atomic_uint_least64_t (C++11) | std::atomic<std::uint_least64_t> (typedef)[edit] |
atomic_int_fast8_t (C++11) | std::atomic<std::int_fast8_t> (typedef)[edit] |
atomic_uint_fast8_t (C++11) | std::atomic<std::uint_fast8_t> (typedef)[edit] |
atomic_int_fast16_t (C++11) | std::atomic<std::int_fast16_t> (typedef)[edit] |
atomic_uint_fast16_t (C++11) | std::atomic<std::uint_fast16_t> (typedef)[edit] |
atomic_int_fast32_t (C++11) | std::atomic<std::int_fast32_t> (typedef)[edit] |
atomic_uint_fast32_t (C++11) | std::atomic<std::uint_fast32_t> (typedef)[edit] |
atomic_int_fast64_t (C++11) | std::atomic<std::int_fast64_t> (typedef)[edit] |
atomic_uint_fast64_t (C++11) | std::atomic<std::uint_fast64_t> (typedef)[edit] |
atomic_intptr_t (C++11)(optional) | std::atomic<std::intptr_t> (typedef)[edit] |
atomic_uintptr_t (C++11)(optional) | std::atomic<std::uintptr_t> (typedef)[edit] |
atomic_size_t (C++11) | std::atomic<std::size_t> (typedef)[edit] |
atomic_ptrdiff_t (C++11) | std::atomic<std::ptrdiff_t> (typedef)[edit] |
atomic_intmax_t (C++11) | std::atomic<std::intmax_t> (typedef)[edit] |
atomic_uintmax_t (C++11) | std::atomic<std::uintmax_t> (typedef)[edit] |
Aliases for special-purpose types | |
atomic_signed_lock_free (C++20) | a signed integral atomic type that is lock-free and for which waiting/notifying is most efficient (typedef)[edit] |
atomic_unsigned_lock_free (C++20) | an unsigned integral atomic type that is lock-free and for which waiting/notifying is most efficient (typedef)[edit] |
std::atomic_intN_t,std::atomic_uintN_t,std::atomic_intptr_t, andstd::atomic_uintptr_t are defined if and only ifstd::intN_t,std::uintN_t,std::intptr_t, andstd::uintptr_t are defined, respectively.
| (since C++20) |
There are non-member function template equivalents for all member functions ofstd::atomic. Those non-member functions may be additionally overloaded for types that are not specializations ofstd::atomic, but are able to guarantee atomicity. The only such type in the standard library isstd::shared_ptr<U>.
_Atomic is akeyword and used to provideatomic types in C.
Implementations are recommended to ensure that the representation of_Atomic(T) in C is same as that ofstd::atomic<T> in C++ for every possible typeT. 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.
| Feature-test macro | Value | Std | Feature |
|---|---|---|---|
__cpp_lib_atomic_ref | 201806L | (C++20) | std::atomic_ref |
__cpp_lib_constexpr_atomic | 202411L | (C++26) | constexprstd::atomic andstd::atomic_ref |
#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 100000The non-atomic counter is 69696
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 optional fixed width integer types were missing | added |
| LWG 3012 | C++11 | std::atomic<T> was permitted for anyTthat is trivially copyable but not copyable | such specializations are forbidden |
| LWG 3949 | C++17 | the wording requiringstd::atomic<bool> to have a trivial destructor was accidently dropped in C++17 | added back |
| LWG 4069 (P3323R1) | C++11 | support for cv-qualifiedT was questionable | disallowT being cv-qualified |
| P0558R1 | C++11 | template argument deduction for some functions for atomic types might accidently fail; invalid pointer operations were provided | specification was substantially rewritten: member typedefs value_typeand difference_type are added |
(C++11) | the lock-free boolean atomic type (class)[edit] |
(C++20) | atomic shared pointer (class template specialization)[edit] |
(C++20) | atomic weak pointer (class template specialization)[edit] |
C documentation forAtomic types | |