• Class / Function / Type

      std::
    • Header file

      <>
    • Other / All

    最終更新日時(UTC):
    が更新

    履歴 編集

    class template
    <tuple>

    std::tuple

    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 tuplei番目の要素を参照する 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

    処理系

    関連項目

    参照