SHOEISHA iD

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

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

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

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

N個以上の要素をまとめられる「tuple」

tuple(2/2)

要素のアクセス

 tupleの(0を起点として)第n番目の要素は関数get<n>を介してアクセスします。ただしnは定数でなくてはなりません。get<n>は参照を返すので、左辺値に用いることで要素への代入が可能です。

getによる参照と代入
#include <iostream>
#include <string>
#include <boost/tr1/tuple.hpp> // tuple

using namespace std;

int main() {
  tr1::tuple<string,int,double> exam;
  tr1::get<0>(exam) = "Steve";
  tr1::get<1>(exam) = 567;
  tr1::get<2>(exam) = tr1::get<1>(exam) / 5.0;
  cout << tr1::get<0>(exam) << "君の"
         " 得点=" << tr1::get<1>(exam) <<
         " 平均=" << tr1::get<2>(exam) << endl;
  // Steve君の 得点=567 平均=113.4
}

 また、pairとのインターフェースの統一のため、pairに対しても関数get<n>が適用できます。

pairに対してgetする
#include <iostream>
#include <string>
#include <utility> // pair
#include <boost/tr1/tuple.hpp> // tuple

using namespace std;

int main() {
  pair<string,int> police = make_pair("???", 110);
  tr1::get<0>(police) = "おまわりさん";

  cout << tr1::get<0>(police) << ':' << tr1::get<1>(police) << endl;
}

一括代入/一括参照

 pairにおけるmake_pairと同様、tupleには関数make_tupleが用意されています。

 また、関数tieによって複数の変数に一括して読みだすことができます。

make_pair/tie
#include <iostream>
#include <string>
#include <boost/tr1/tuple.hpp> // tuple

using namespace std;

int main() {
  tr1::tuple<string,int,double> exam;
  exam = tr1::make_tuple("Steve", 567, 567/5.0);
  string name;
  double mean;
  // tie:使わない要素には ignore(無視) を指定すべし
  tr1::tie(name, tr1::ignore, mean) = exam;
  cout << name << "君の平均点は" << mean << endl;
  // Steve君の平均点は113.4
}

比較

 tupleの比較演算==!=<<=>>=は各要素を左から順に比較します。比較の途中で真偽が確定すれば、それ以降の比較は行われません。

tupleの比較はshortcutされる
#include <iostream>
#include <boost/tr1/tuple.hpp> // tuple

using namespace std;

struct Value {
  int n_;
  Value(int n) : n_(n) {}
};

bool operator==(const Value& x, const Value& y) {
  bool result = ( x.n_ == y.n_ );
  cout << x.n_ << (result ? "==":"!=") << y.n_ << endl;
  return result;
}

bool operator<(const Value& x, const Value& y) {
  bool result = ( x.n_ < y.n_ );
  cout << x.n_ << (result ? "<":">=") << y.n_ << endl;
  return result;
}

int main() {
  typedef tr1::tuple<Value,Value,Value> triple;
  triple x(12,34,56);
  triple y(12,43,56);
  // 第2要素までの比較で真偽が確定するため、
  // 第3要素の比較は行われない
  cout << "x == y :" << boolalpha << (x == y) << endl;
  cout << "x <  y :" << boolalpha << (x <  y) << endl;
}
実行結果
12==12
34!=43
x == y :false
12>=12
12>=12
34<43
x <  y :true

tuple_size、tuple_element

 tuple_size<Tuple>::valueはTupleの要素数、

 tuple_element<N,Tuple>::typeはTupleのN番目の要素の型となります。

tuple_size、 tuple_element
#include <iostream>
#include <string>
#include <boost/tr1/tuple.hpp> // tuple

using namespace std;

// Tupleの要素数
template<typename Tuple>
int members(const Tuple&) {
  return tr1::tuple_size<Tuple>::value;
}

// TupleのN番目を'+'する
template<int N, typename Tuple>
typename tr1::tuple_element<N,Tuple>::type 
plus(const Tuple& x, const Tuple& y) {
  return tr1::get<N>(x) + tr1::get<N>(y);
}

int main() {
  tr1::tuple<string,int> t1("Hello",12);
  tr1::tuple<string,int> t2("World",34);
  cout << members(t1) << " members." << endl;
  cout << plus<0>(t1,t2) << endl;
  cout << plus<1>(t1,t2) << endl;
}
実行結果
2 members.
HelloWorld
46

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

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

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/2134 2008/02/04 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング