std::exchange
提供: cppreference.com
ヘッダ <utility> で定義 | ||
template<class T, class U = T > T exchange( T& obj, U&& new_value ); | (C++14以上) (C++20未満) | |
template<class T, class U = T > constexpr T exchange( T& obj, U&& new_value ); | (C++20以上) | |
obj
の値を new_value
の値で置き換え、 obj
の古い値を返します。
目次 |
[編集]引数
obj | - | 値を置き換えるオブジェクト |
new_value | - | obj に代入する値 |
型の要件 | ||
-T は MoveConstructible の要件を満たさなければなりません。 また、 U 型のオブジェクトから T 型のオブジェクトへのムーブ代入も可能でなければなりません |
[編集]戻り値
obj
の古い値。
[編集]例外
(なし)
[編集]実装例
template<class T, class U = T> T exchange(T& obj, U&& new_value){ T old_value = std::move(obj); obj =std::forward<U>(new_value);return old_value;} |
[編集]ノート
この関数はムーブ代入演算子やムーブコンストラクタを実装するときに使用することができます。
struct S {int* p;int n; S(S&& other):p{std::exchange(other.p, nullptr)} ,n{std::exchange(other.n, 0)}{} S& operator=(S&& other){if(this !=&other){ p = std::exchange(other.p, nullptr);// p をムーブし、 other.p に nullptr を残します。 n = std::exchange(other.n, 0);// n をムーブし、 other.n に 0 を残します。}return*this;}};
[編集]例
Run this code
#include <iostream>#include <utility>#include <vector>#include <iterator> class stream {public: using flags_type =int; public: flags_type flags()const{return flags_;} // flags_ を newf で置き換え、古い値を返します。 flags_type flags(flags_type newf){return std::exchange(flags_, newf);} private: flags_type flags_ =0;}; void f(){std::cout<<"f()";} int main(){ stream s; std::cout<< s.flags()<<'\n';std::cout<< s.flags(12)<<'\n';std::cout<< s.flags()<<"\n\n"; std::vector<int> v; // 第2テンプレート引数はデフォルト値を持つため、// 第2引数として波括弧初期化子リストを使用することができます。// 以下の式は std::exchange(v, std::vector<int>{1,2,3,4}); と同等です。 std::exchange(v, {1,2,3,4}); std::copy(begin(v),end(v), std::ostream_iterator<int>(std::cout,", ")); std::cout<<"\n\n"; void(*fun)(); // テンプレート引数のデフォルト値により、// 第2引数として通常の関数を使用することもできます。// 以下の式は std::exchange(fun, static_cast<void(*)()>(f)); と同等です。 std::exchange(fun,f); fun();}
出力:
0 0 12 1, 2, 3, 4, f()
[編集]関連項目
2つのオブジェクトの値を入れ替えます (関数テンプレート) | |
(C++11)(C++11) | アトミックオブジェクトの値を非アトミック引数でアトミックに置き換え、そのアトミックの古い値を返します (関数テンプレート) |