std::atomic_ref::atomic_ref(3)

NAME
std::atomic_ref::atomic_ref - std::atomic_ref::atomic_ref

Synopsis
   explicit atomic_ref( T& obj ); (1) (since C++20)
   atomic_ref( const atomic_ref& ref ) noexcept; (2) (since C++20)
   Constructs a new atomic_ref object.
   1) Constructs an atomic_ref object referencing the object obj. The behavior is
   undefined if obj is not aligned to required_alignment.
   2) Constructs an atomic_ref object referencing the object referenced by ref.

Parameters
   obj - object to reference
   ref - another atomic_ref object to copy from

Example
   The program increments the values in a container using several threads. Then the
   final sum is printed. Non-atomic access may "loss" the results of some operations
   due to data-races. // Run this code
 #include <atomic>
 #include <iostream>
 #include <numeric>
 #include <thread>
 #include <vector>
 int main()
 {
     using Data = std::vector<char>;
     auto inc_atomically = [](Data& data)
     {
         for (Data::value_type& x : data)
         {
             auto xx = std::atomic_ref<Data::value_type>(x);
             ++xx; // atomic read-modify-write
         }
     };
     auto inc_directly = [](Data& data)
     {
         for (Data::value_type& x : data)
             ++x;
     };
     auto test_run = [](const auto Fun)
     {
         Data data(10'000'000);
         {
             std::jthread j1{Fun, std::ref(data)};
             std::jthread j2{Fun, std::ref(data)};
             std::jthread j3{Fun, std::ref(data)};
             std::jthread j4{Fun, std::ref(data)};
         }
         std::cout << "sum = " << std::accumulate(cbegin(data), cend(data), 0) << '\n';
     };
     test_run(inc_atomically);
     test_run(inc_directly);
 }

Possible output:
 sum = 40000000
 sum = 39994973