[[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;
}

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS