T fetch_sub(difference_type operand,
memory_order order = memory_order_seq_cst
) volatile noexcept; // (1) C++11
T fetch_sub(difference_type operand,
memory_order order = memory_order_seq_cst
) noexcept; // (2) C++11
概要
減算を行う
要件
- (1), (2) :
- C++17 :
std::atomic<T*>
の場合、型T
がオブジェクト型であること。型T
がvoid*
や関数ポインタであってはならない
- C++17 :
- (1) :
- C++20 :
atomic<T>::is_always_lock_free
がtrue
であること
- C++20 :
効果
order
で指定されたメモリオーダーにしたがって、現在の値にoperand
を減算した値でアトミックに置き換える
戻り値
変更前の値が返される
備考
- この関数は、
atomic
クラスの整数型、浮動小数点数型 (C++20)、ポインタに対する特殊化で定義される - 整数型
- 符号付き整数型に対しては、符号なし整数型に変換されたかのようにしたあと演算が行われ、結果は符号付き整数型になる。未定義動作はない
- 浮動小数点数型 (C++20)
- 演算結果が、その型で表現できない値であった場合、結果は未規定値になる。ただしその操作によって未定義動作は起こらない
- 浮動小数点数型に対する操作は
std::numeric_limits<floating-point>
トレイトに準拠する - 浮動小数点数型に対するアトミック操作の浮動小数点環境は、呼び出しスレッドの浮動小数点環境とは異なる可能性がある
- ポインタ型
例
整数の例 (C++11)
#include <iostream>
#include <atomic>
int main()
{
std::atomic<int> x(3);
int before = x.fetch_sub(2);
std::cout << before << std::endl;
std::cout << x.load() << std::endl;
}
出力
3
1
浮動小数点数の例 (C++20)
#include <iostream>
#include <atomic>
int main()
{
std::atomic<float> x{3.14f};
float before = x.fetch_sub(1.25f);
std::cout << before << std::endl;
std::cout << x.load() << std::endl;
}
出力
3.14
1.89
複数スレッドから減算する例 (C++11)
#include <iostream>
#include <atomic>
#include <thread>
int main()
{
std::atomic<int> x{10};
// 複数スレッドで減算を呼んでも、
// 最終的に全てのスレッドでの減算が処理された値になる
std::thread t1 {[&x] {
x.fetch_sub(1);
}};
std::thread t2 {[&x] {
x.fetch_sub(2);
}};
t1.join();
t2.join();
std::cout << x.load() << std::endl;
}
出力
7
バージョン
言語
- C++11
処理系
- Clang: 3.2 ✅
- GCC: 4.7.0 ✅
- Visual C++: 2012 ✅, 2013 ✅
関連項目
参照
- P0558R1 Resolving
atomic<T>
named base class inconsistencies- C++17での、オブジェクト型であることの制約追加
- P0020R6 Floating Point Atomic
- C++20での、浮動小数点数版の追加
- P1831R1 Deprecating
volatile
: library- C++20での、
volatile
版への制約追加
- C++20での、