はじめに
C++で、関数の戻り値として複数の値を返したい場合や、いくつかの異なる型のデータを一時的に一つの変数で扱いたい場合があります。この目的のために、C++11では std::tuple
というクラスが導入されました。
std::tuple
は、std::pair
の一般化版と考えることができ、任意の個数(コンパイラに依存しますが、通常は多数)の、任意の型の要素を保持できます。
この記事では、<tuple>
ヘッダーで提供される std::tuple
の基本的な使い方(生成、値の変更、要素へのアクセス)を解説します。
【前提】C++11とは?
C++11(シーピープラスいちいち)は、2011年に正式化されたC++言語のメジャーアップデート版です。std::tuple
はこのC++11で導入された機能のため、利用するにはC++11以降に対応したコンパイラが必要です。
std::tuple
を使ったサンプルコード
このコードは、int
, string
, double
という3つの異なる型の値を保持する tuple
を作成し、その値を変更したり、個々の要素を取り出して表示したりする方法を示します。
完成コード
#include <iostream>
#include <tuple> // tuple, make_tuple, get を使うために必要
#include <string>
using namespace std;
int main() {
// 1. tupleの生成 (コンストラクタで初期化)
tuple<int, string, double> product_data(101, "りんご", 120.5);
// 2. get<N>(tuple)で、N番目(0始まり)の要素にアクセス
cout << "--- 初期値 ---" << endl;
cout << "ID: " << get<0>(product_data) << endl;
cout << "商品名: " << get<1>(product_data) << endl;
cout << "価格: " << get<2>(product_data) << endl;
// 3. make_tupleで新しいtupleを作成し、代入
product_data = make_tuple(202, "みかん", 80.0);
cout << "\n--- 値を変更後 ---" << endl;
cout << "ID: " << get<0>(product_data) << endl;
cout << "商品名: " << get<1>(product_data) << endl;
cout << "価格: " << get<2>(product_data) << endl;
return 0;
}
コードの解説
1. tuple
の生成
tuple<int, string, double> product_data(...);
std::tuple
を使うには、< >
の中に、格納したい値のデータ型を順番に列挙します。- コンストラクタの引数に、それらの型に対応する初期値を渡すことで、オブジェクトを生成できます。
2. std::make_tuple
product_data = make_tuple(202, "みかん", 80.0);
std::make_tuple
は、引数として渡された値から、対応する型のtuple
オブジェクトを自動で生成して返すヘルパー関数です。tuple<int, string, double> t = {202, "みかん", 80.0};
のように、初期化子リストを使うこともできます。
3. 要素へのアクセス (std::get
)
cout << get<0>(product_data) << endl;
tuple
の各要素にアクセスするには、std::get
を使います。
get<N>(タプル変数)
:< >
の中に、アクセスしたい要素のインデックス番号(0始まり)を定数で指定します。get<0>
は最初の要素(int
)、get<1>
は2番目の要素(string
)、get<2>
は3番目の要素(double
)をそれぞれ返します。
注意: get
のインデックスは、変数ではなく、コンパイル時に確定している定数(リテラル値)でなければなりません。for
ループの中で get<i>
のように使うことはできません。
まとめ
今回は、C++11の std::tuple
を使って、複数の異なる型の値を一つのオブジェクトにまとめる方法を解説しました。
std::tuple<T1, T2, ...>
で、任意の型の組み合わせを定義できる。std::make_tuple
で、値から簡単にtuple
を生成できる。std::get<N>
で、0始まりのインデックスを指定して、N番目の要素にアクセスする。
tuple
は、特に「関数から複数の値を返したい」という場面で、構造体をわざわざ定義するまでもない、一時的なデータの入れ物として非常に役立ちます。