std::atomic<T>::operator++,++(int),--,--(int)

来自cppreference.com
< cpp‎ | atomic‎ | atomic
 
 
并发支持库
线程
(C++11)
(C++20)
(C++20)
this_thread 命名空间
(C++11)
(C++11)
(C++11)
互斥
(C++11)
(C++11)  
通用锁管理
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
条件变量
(C++11)
信号量
闩与屏障
(C++20)
(C++20)
未来体
(C++11)
(C++11)
(C++11)
(C++11)
安全回收
(C++26)
(C++26)
风险指针





原子类型
(C++11)
(C++20)
原子类型的初始化
(C++11)(C++20 中弃用)
(C++11)(C++20 中弃用)
内存定序
原子操作的自由函数
原子标志的自由函数
 
 
atomic<整数类型 > 特化才有的成员
T operator++() noexcept;
(1) (C++11 起)
T operator++() volatile noexcept;
(2) (C++11 起)
T operator++( int ) noexcept;
(3) (C++11 起)
T operator++( int ) volatile noexcept;
(4) (C++11 起)
T operator--() noexcept;
(5) (C++11 起)
T operator--() volatile noexcept;
(6) (C++11 起)
T operator--( int ) noexcept;
(7) (C++11 起)
T operator--( int ) volatile noexcept;
(8) (C++11 起)
atomic<T*> 部分特化才有的成员
T* operator++() noexcept;
(9) (C++11 起)
T* operator++() volatile noexcept;
(10) (C++11 起)
T* operator++( int ) noexcept;
(11) (C++11 起)
T* operator++( int ) volatile noexcept;
(12) (C++11 起)
T* operator--() noexcept;
(13) (C++11 起)
T* operator--() volatile noexcept;
(14) (C++11 起)
T* operator--( int ) noexcept;
(15) (C++11 起)
T* operator--( int ) volatile noexcept;
(16) (C++11 起)

原子地自增或自减当前值。操作为读-修改-写操作。

  • operator++() 进行原子的前自增。等价于 return fetch_add(1) + 1;
  • operator++(int) 进行原子的后自增。等价于 return fetch_add(1);
  • operator--() 进行原子的前自减。等价于 return fetch_sub(1) - 1;
  • operator--(int) 进行原子的后自减。等价于 return fetch_sub(1);
1-8) 对于有符号整数类型,算术定义为使用补码表示。没有未定义的结果。
9-16) 结果可能是未定义地址,但此外这些操作不会有未定义行为。
如果 T 不是完整对象类型,那么程序非良构。

volatile 重载在参与重载决议且 std::atomic<T>::is_always_lock_freefalse 时被弃用。

(C++20 起)

返回值

operator++()operator--() 返回修改后的原子变量的值。正式地说,*this修改顺序中紧接此函数生效前的值的自增/自减的结果。

operator++(int)operator--(int) 返回修改前的原子变量的值。正式地说,*this修改顺序中紧接此函数生效前的值。

注解

与大多数前自增和自减运算符不同,原子类型的前自增和自减运算符不返回被修改对象的引用。它们代之以返回存储值的副本。

示例

#include <atomic>
#include <chrono>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <random>
#include <string>
#include <thread>
 
std::atomic<int> atomic_count{0};
 
std::mutex cout_mutex;
int completed_writes{0};
 
constexpr int global_max_count{72};
constexpr int writes_per_line{8};
constexpr int max_delay{100};
 
template<int Max>
int random_value()
{
    static std::uniform_int_distribution<int> distr{1, Max};
    static std::random_device engine;
    static std::mt19937 noise{engine()};
    static std::mutex rand_mutex;
    std::lock_guard lock{rand_mutex};
    return distr(noise);
}
 
int main()
{
    auto work = [](const std::string id)
    {
        for (int count{}; (count = ++atomic_count) <= global_max_count;)
        {
            std::this_thread::sleep_for(
                std::chrono::milliseconds(random_value<max_delay>()));
 
            // 打印线程的 id 和 count 值
            {
                std::lock_guard lock{cout_mutex};
 
                const bool new_line = ++completed_writes % writes_per_line == 0;
 
                std::cout << id << std::setw(3) << count << "  "
                          << (new_line ? "\n" : "") << std::flush;
            }
        }
    };
 
    std::jthread j1(work, "░"), j2(work, "▒"), j3(work, "▓"), j4(work, "█");
}

可能的输出:

▒  2  ░  1  ▒  5  ▒  7  █  4  ░  6  ▓  3  ▒  8  
▓ 11  █  9  ▓ 13  ░ 10  █ 14  ▒ 12  ░ 16  ░ 19  
▓ 15  ▒ 18  ▓ 21  ▒ 22  █ 17  █ 25  ▒ 24  █ 26  
░ 20  ░ 29  ▒ 27  ▓ 23  ▒ 31  ▒ 33  ▓ 32  █ 28  
░ 30  ░ 37  ▒ 34  ▓ 35  █ 36  █ 41  ▓ 40  ▒ 39  
░ 38  ▓ 43  █ 42  ▓ 46  ▓ 48  █ 47  █ 50  ░ 45  
▒ 44  ▒ 53  ▒ 54  ▓ 49  ▒ 55  █ 51  ▒ 57  █ 58  
░ 52  ▓ 56  ░ 61  ▒ 59  █ 60  ▓ 62  ▒ 64  ░ 63  
░ 68  ▓ 66  █ 65  █ 71  ▒ 67  ▓ 70  ░ 69  █ 72

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
P0558R1 C++11 允许进行指向(可有 cv 限定的)void 或函数的指针运算 使之非良构

参阅

原子地将实参加到存储于原子对象的值上,并返回先前保有的值
(公开成员函数)
原子地从存储于原子对象的值减去实参,并获得先前保有的值
(公开成员函数)
与原子值进行加、减
(公开成员函数)
与原子值进行逐位与、或、异或
(公开成员函数)