2018年01月18日
《その242》 関数 swap
関数 swap
関数 swap は、2つの値を交換しますが、
関数テンプレートとして与えられるその定義ついては、2011年の C++11 で変更されています。
【1】C++11 の前までは、<algorithm>ヘッダで次のように定義されていました。
templatevoid std::swap(T& a, T& b) {
T temp = a;
a = b;
b = temp;
}
【2】C++11 以後は、<utility>ヘッダで次のように定義されています。
templatevoid std::swap(T& a, T& b) {
T temp = std::move(a);
a = std::move(b);
b = std::move(temp);
}
「 move 」 に関して、新版明解C++中級編では、関数テンプレート swap の紹介をしている程度で索引にも記載がありません。
中級編のレベルでは まだまだここはちょっと、ということでしょうか ( _ _ )...
古いほうの定義では、
T temp = a; でコピーコンストラクタが、
a = b; で代入演算子が、
b = temp; でも代入演算子が、
それぞれはたらくので、コスト的に不利ということなのだと思います。
それに対して、move を使うほうの定義は、コピーコンストラクタや代入演算子を使わずに、
かなり乱暴で大雑把な表現になりますが、手渡す感じで値の移動を行うのでコスト的に有利、ということでしょうか。
ただし、
『 move は引数を移動しません。 代わりに、その引数 (左辺値である可能性がある) を無条件に右辺値参照にキャストすることにより、型の移動が有効である場合、コンパイラは引数 に渡された値をコピーではなく移動できます。 型の移動が有効ではない場合は、代わりにコピーされます。https://msdn.microsoft.com/ja-jp/library/ee390941.aspx 』
つまり、引数を身軽な右辺値参照にキャストして手渡すということだと思います。結果として、値が移動したイメージ・・・という解釈でいいのかどうか。とりあえず、新版明解C++中級編ではスルーしているので、自分なりの解釈で無理やり納得して、先に進みます レ(゚∀゚;)ヘ
以下は利用例です。
#include <iostream>
using namespace std;
class C {
public:
int n;
C(int x = 0) : n(x) { }
};
template<class T> void swp_org(T& a, T& b) {
T t = a; a = b; b = t;
}
template<class T> void swp_mov(T& a, T& b) {
T t = move(a); a = move(b); b = move(t);
}
int main() {
C s(1);
C t(2);
cout << s.n << " " << t.n << '\n';
swp_org(s, t);
cout << s.n << " " << t.n << '\n';
swp_mov(s, t);
cout << s.n << " " << t.n << '\n';
}
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/7211262
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック