- 追加された行はこの色です。
- 削除された行はこの色です。
[[C++ Tips]]
* 参照型のメンバをもつクラスのコンテナとソート [#j00f0661]
#include <cstdio>
#include <list>
#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
// 参照を持つクラスのswap
namespace {
struct Hoge {
int& instance_;
Hoge(int& i) : instance_(i)
{}
Hoge(const Hoge& h) : instance_(h.instance_) {}
// Sutterさんのoperator=
Hoge& operator = (Hoge h) {
swap(h);
return *this;
}
// リファレンスタイプのインスタンスは通常の方法ではswapできないので、
// コピーコンストラクタとnewの第二構文を使った初期化を使って実現する。
void swap(Hoge& h) {
Hoge tmp(h); // hをコピー
h.~Hoge(); // hを破棄
new(&h) Hoge(*this); // hのアドレスにthisのコピーを生成
this->~Hoge(); // thisを破棄
new(this) Hoge(tmp); // thisのアドレスにhのコピーであるtmpを生成
}
bool operator < (const Hoge& h) const {
return instance_ < h.instance_;
}
};
inline void swap(Hoge& h1, Hoge& h2) {
h1.swap(h2);
}
// output用
void print(const Hoge& h) {
printf("%d\n", h.instance_);
}
}
int main(int argc, char* argv[])
{
int i1 = 1;
int i2 = 2;
int i3 = 3;
Hoge h1(i1), h2(i2), h3(i3);
std::vector<Hoge> vectorhoge;
vectorhoge.push_back(h3); // operator =がないとvector::push_backはでき ない
vectorhoge.push_back(h2);
vectorhoge.push_back(h1);
std::back_inserter(vectorhoge) = h1;
std::sort(vectorhoge.begin(), vectorhoge.end()); // operator =がないと vector::push_backはできない
std::cout << "vector sort" << std::endl;
std::for_each(vectorhoge.begin(), vectorhoge.end(), print);
std::list<Hoge> listhoge;
listhoge.push_back(h3);
listhoge.push_back(h2);
listhoge.push_back(h1);
std::back_inserter(listhoge) = h1;
listhoge.sort();
std::cout << "list sort" << std::endl;
std::for_each(listhoge.begin(), listhoge.end(), print);
return 0;
}