namespace std {
template <class... Args>
class tuple;
}
概要
tuple
型は、複数の型の値を保持する「タプル」を表現するためのクラスである。
pair
型は2つの型の値を保持する「組」を表現することができるが、tuple
ではN個の型の値を扱うことができる。
メンバ関数
名前 | 説明 | 対応バージョン |
---|---|---|
(constructor) |
コンストラクタ | C++11 |
operator= |
代入演算子 | C++11 |
swap |
異なるtuple オブジェクトと値を入れ替える |
C++11 |
非メンバ関数
タプル生成関数
名前 | 説明 | 対応バージョン |
---|---|---|
ignore |
無視する要素のプレースホルダー(constant variable) | C++11 |
make_tuple |
引数のコピーからタプルを生成する | C++11 |
forward_as_tuple |
引数の完全な型からタプルを生成する | C++11 |
tie |
引数への参照からタプルを生成する | C++11 |
tuple_cat |
複数のタプルから1つのタプルを生成する | C++11 |
要素アクセス
名前 | 説明 | 対応バージョン |
---|---|---|
get |
tuple のi 番目の要素を参照する |
C++11 |
入れ替え
名前 | 説明 | 対応バージョン |
---|---|---|
swap |
2つのtuple オブジェクトを入れ替える |
C++11 |
比較演算子
名前 | 説明 | 対応バージョン |
---|---|---|
operator== |
等値比較を行う | C++11 |
operator!= |
非等値比較を行う | C++11 |
operator<=> |
三方比較を行う | C++20 |
operator< |
左辺が右辺よりも小さいか比較を行う | C++11 |
operator<= |
左辺が右辺以下か比較を行う | C++11 |
operator> |
左辺が右辺より大きいか比較を行う | C++11 |
operator>= |
左辺が右辺以上か比較を行う | C++11 |
推論補助
名前 | 説明 | 対応バージョン |
---|---|---|
(deduction_guide) |
クラステンプレートの推論補助 | C++17 |
tuple-like とのユーティリティ
名前 | 説明 | 対応バージョン |
---|---|---|
operator== |
tuple-like なオブジェクトとの等値比較を行う |
C++23 |
operator<=> |
tuple-like なオブジェクトとの三方比較を行う |
C++23 |
common_type |
tuple-like なオブジェクトとの共通型を取得できるようにする特殊化 |
C++23 |
basic_common_reference |
tuple-like なオブジェクトとの共通の参照型を取得出来るようにする特殊化 |
C++23 |
例
基本的な使い方 (C++11)
#include <iostream>
#include <tuple>
#include <string>
int main()
{
// 3要素のタプルを作る
std::tuple<int, char, std::string> t = std::make_tuple(1, 'a', "hello");
// 0番目の要素を参照
int& i = std::get<0>(t);
std::cout << i << std::endl;
// 2番目の要素を参照
std::string& s = std::get<2>(t);
std::cout << s << std::endl;
}
出力
1
hello
基本的な使い方 (C++17)
#include <iostream>
#include <tuple>
#include <string>
// 関数から複数の値を返す
std::tuple<int, char, std::string> f()
{
// std::make_tuple()はほとんどの状況で必要ない
return {1, 'a', "hello"};
}
int main()
{
// 構造化束縛でタプルを分解して、それぞれの要素を代入
auto [a, b, c] = f();
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << c << std::endl;
}
出力
1
a
hello
プロキシ参照としての使い方(C++23)
C++23 でzip_view
などが追加されたことに伴い、すべての要素がプロキシ参照であるようなtuple
はプロキシ参照として使用することが出来るようになった。
#include <iostream>
#include <tuple>
#include <string_view>
#include <format>
struct A
{
A(int i, double d)
: i(i)
, d(d)
{}
std::tuple<int&, double&> f()
{
// this が A* なので
// i: int
// d: double
// ということと同じ
return {i, d};
}
std::tuple<const int&, const double&> f() const
{
// this が const A* なので
// i: const int
// d: const double
// ということと同じ
return {i, d};
}
private:
int i;
double d;
};
int main()
{
// プロキシ参照である tuple の性質
{
A a{0, 0.0};
// std::tuple<int&, double&>
/***/ auto /***/ proxy = a.f();
// const std::tuple<int&, double&>
const auto const_proxy = a.f();
// std::tuple<const int&, const double&>
/***/ auto /***/ proxy_to_const = std::as_const(a).f();
// const std::tuple<const int&, const double&>
const auto const_proxy_to_const = std::as_const(a).f();
// OK(各要素が指すオブジェクトの値について、代入操作がなされる)
proxy = a.f();
const_proxy = a.f();
// NG(各要素が指すオブジェクトを変更できない!)
// proxy_to_const = a.f();
// const_proxy_to_const = a.f();
}
// 使い方
{
auto print = [](std::string_view prefix, A& a) {
// 構造化束縛で分解
// i: int&
// d: double&
auto [i, d] = a.f();
std::cout << std::format("{}: i={}, d={}\n", prefix, i, d);
};
A a{0, 0.0}, b{1, 1.0};
print("before a", a);
print("before b", b);
// プロキシ参照として使える tuple 同士の swap 操作で
// 問題なく各要素が指す先のオブジェクトについて swap 操作が行える
std::ranges::swap(a.f(), b.f());
print("after a", a);
print("after b", b);
}
}
出力
before a: i=0, d=0
before b: i=1, d=1
after a: i=1, d=1
after b: i=0, d=0
バージョン
言語
- C++11
処理系
- Clang: 3.0 ✅
- GCC: 4.3.4 ✅, 4.4.4 ✅, 4.5.2 ✅, 4.6.1 ✅
- ICC: ?
- Visual C++: 2008 ✅, 2010 ✅