SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

BoostでC++0xのライブラリ「TR1」を先取りしよう

BoostでC++0xのライブラリ「TR1」を先取りしよう (4)

bindとfunction


function

 さて、汎用バインダbindによって生成された関数オブジェクトを変数に格納し、いくつものアルゴリズムで使いまわすことを考えてみましょう。そのためにはbindが生成した関数オブジェクトの'型'をもつ変数を宣言しなければなりません。

bindの生成する関数オブジェクトの'型'
  cout << typeid(tr1::bind(&Sandwich::make, _1, _2, _3)).name();
実行結果
class boost::_bi::bind_t<class std::basic_string<char,
struct std::char_traits<char>,class std::allocator<char> >,
class boost::_mfi::cmf2<class std::basic_string<char,
struct std::char_traits<char>,class std::allocator<char> >,
class Sandwich,class std::basic_string<char,
struct std::char_traits<char>,class std::allocator<char> > const &,
class std::basic_string<char,struct std::char_traits<char>,
class std::allocator<char> > const &>,
class boost::_bi::list3<class boost::arg<1>,class boost::arg<2>,class boost::arg<3> > >

 ……とてつもなく複雑な型が作られています。これでは変数を宣言できません。

 クラステンプレートfunctionは関数オブジェクトの汎用的な'型'として機能します。

関数オブジェクトを統一的に扱う
#include <iostream>
#include <algorithm>
#include <functional>
#include <boost/tr1/functional.hpp> 

using namespace std;

// x < y なら true を返す
bool less_int(int x, int y) {
  return x < y;
}

// 昇順/降順のどちらにも使える比較関数
template<typename T>
bool compare(T x, T y, bool descend) {
  return descend ? (x < y) : (y < x);
}

int main() {
  const int N = 8;
  int data[N] = { 0, -1, 1, -2, 2, -3, 3, 4 };
  // template引数がちょっと特殊。
  // 戻り値 (変数,変数...) という形式。
  tr1::function<bool (int,int)> comp;
  // 昇順にソート
  using namespace tr1::placeholders;
  comp = tr1::bind(&compare<int>, _1, _2, true);
  sort(data, data+N, comp);
  for ( int i = 0; i < N; ++i ) cout << data[i] << ' '; cout << endl;
  // 同じく昇順にソート
  comp = &less_int;
  sort(data, data+N, comp);
  for ( int i = 0; i < N; ++i ) cout << data[i] << ' '; cout << endl;
  // これもやっぱり降順にソート
  comp = less<int>();
  sort(data, data+N, comp);
  for ( int i = 0; i < N; ++i ) cout << data[i] << ' '; cout << endl;
}
修正履歴

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
BoostでC++0xのライブラリ「TR1」を先取りしよう連載記事一覧

もっと読む

この記事の著者

επιστημη(エピステーメー)

C++に首まで浸かったプログラマ。Microsoft MVP, Visual C++ (2004.01~2018.06) "だった"りわんくま同盟でたまにセッションスピーカやったり中国茶淹れてにわか茶...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/2158 2008/02/15 08:49

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー