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

履歴 編集

function
<tuple>

std::tuple::コンストラクタ(C++11)

constexpr tuple();                                        // (1) C++11
EXPLICIT constexpr tuple();                               // (1) C++17
explicit(see below) constexpr tuple();                    // (1) C++20

explicit tuple(const Types&...);                          // (2) C++11
constexpr explicit tuple(const Types&...);                // (2) C++14
EXPLICIT constexpr tuple(const Types&...);                // (2) C++17
explicit(see below) constexpr tuple(const Types&...);     // (2) C++20

template <class... UTypes>
explicit tuple(UTypes&&...);                              // (3) C++11
template <class... UTypes>
constexpr explicit tuple(UTypes&&...);                    // (3) C++14
template <class... UTypes>
EXPLICIT constexpr tuple(UTypes&&...);                    // (3) C++17
template <class... UTypes>
explicit(see below) constexpr tuple(UTypes&&...);         // (3) C++20

tuple(const tuple&) = default;                            // (4) C++11
tuple(tuple&&) = default;                                 // (5) C++11

template <class... UTypes>
tuple(const tuple<UTypes...>&);                           // (6) C++11
template <class... UTypes>
constexpr tuple(const tuple<UTypes...>&);                 // (6) C++14
template <class... UTypes>
EXPLICIT constexpr tuple(const tuple<UTypes...>&);        // (6) C++17
template <class... UTypes>
explicit(see below) constexpr
  tuple(const tuple<UTypes...>&);                         // (6) C++20

template <class... UTypes>
tuple(tuple<UTypes...>&&);                                // (7) C++11
template <class... UTypes>
constexpr tuple(tuple<UTypes...>&&);                      // (7) C++14
template <class... UTypes>
EXPLICIT constexpr tuple(tuple<UTypes...>&&);             // (7) C++17
template <class... UTypes>
explicit(see below) constexpr tuple(tuple<UTypes...>&&);  // (7) C++20

template <class U1, class U2>
tuple(const pair<U1, U2>&);                               // (8) C++11
template <class U1, class U2>
constexpr tuple(const pair<U1, U2>&);                     // (8) C++14
template <class U1, class U2>
EXPLICIT constexpr tuple(const pair<U1, U2>&);            // (8) C++17
template <class U1, class U2>
explicit(see below) constexpr tuple(const pair<U1, U2>&); // (8) C++20

template <class U1, class U2>
tuple(pair<U1, U2>&&);                                    // (9) C++11
template <class U1, class U2>
constexpr tuple(pair<U1, U2>&&);                          // (9) C++14
template <class U1, class U2>
EXPLICIT constexpr tuple(pair<U1, U2>&&);                 // (9) C++17
template <class U1, class U2>
explicit(see below) constexpr tuple(pair<U1, U2>&&);      // (9) C++20

// アロケータによる構築
template <class Alloc>
tuple(allocator_arg_t, const Alloc& a);                   // (10) C++11
template <class Alloc>
constexpr tuple(allocator_arg_t, const Alloc& a);         // (10) C++20

template <class Alloc>
tuple(allocator_arg_t,
      const Alloc& a,
      const Types&...);                                   // (11) C++11
template <class Alloc>
EXPLICIT tuple(allocator_arg_t,
               const Alloc& a,
               const Types&...);                          // (11) C++17
template <class Alloc>
explicit(see below) constexpr tuple(allocator_arg_t,
                                    const Alloc& a,
                                    const Types&...);     // (11) C++20

template <class Alloc, class... UTypes>
tuple(allocator_arg_t,
      const Alloc& a,
      UTypes&&...);                                       // (12) C++11
template <class Alloc, class... UTypes>
EXPLICIT tuple(allocator_arg_t,
               const Alloc& a,
               UTypes&&...);                              // (12) C++17
template <class Alloc, class... UTypes>
explicit(see below) constexpr tuple(allocator_arg_t,
                                    const Alloc& a,
                                    UTypes&&...);         // (12) C++20

template <class Alloc>
tuple(allocator_arg_t,
      const Alloc& a,
      const tuple&);                                      // (13) C++11
template <class Alloc>
constexpr tuple(allocator_arg_t,
                const Alloc& a,
                const tuple&);                            // (13) C++20

template <class Alloc>
tuple(allocator_arg_t,
      const Alloc& a,
      tuple&&);                                           // (14) C++11
template <class Alloc>
constexpr tuple(allocator_arg_t,
                const Alloc& a,
                tuple&&);                                 // (14) C++20

template <class Alloc, class... UTypes>
tuple(allocator_arg_t,
      const Alloc& a,
      const tuple<UTypes...>&);                           // (15) C++11
template <class Alloc, class... UTypes>
EXPLICIT tuple(allocator_arg_t,
               const Alloc& a,
               const tuple<UTypes...>&);                  // (15) C++17
template <class Alloc, class... UTypes>
explicit(see below) constexpr
  tuple(allocator_arg_t,
        const Alloc& a,
        const tuple<UTypes...>&);                         // (15) C++20

template <class Alloc, class... UTypes>
tuple(allocator_arg_t,
      const Alloc& a,
      tuple<UTypes...>&&);                                // (16) C++11
template <class Alloc, class... UTypes>
EXPLICIT tuple(allocator_arg_t,
               const Alloc& a,
               tuple<UTypes...>&&);                       // (16) C++17
template <class Alloc, class... UTypes>
explicit(see below) constexpr
  tuple(allocator_arg_t,
        const Alloc& a,
        tuple<UTypes...>&&);                              // (16) C++20

template <class Alloc, class U1, class U2>
tuple(allocator_arg_t,
      const Alloc& a,
      const pair<U1, U2>&);                               // (17) C++11
template <class Alloc, class U1, class U2>
EXPLICIT tuple(allocator_arg_t,
               const Alloc& a,
               const pair<U1, U2>&);                      // (17) C++17
template <class Alloc, class U1, class U2>
explicit(see below) constexpr
  tuple(allocator_arg_t,
        const Alloc& a,
        const pair<U1, U2>&);                             // (17) C++20

template <class Alloc, class U1, class U2>
tuple(allocator_arg_t,
      const Alloc& a,
      pair<U1, U2>&&);                                    // (18) C++11
template <class Alloc, class U1, class U2>
EXPLICIT tuple(allocator_arg_t,
               const Alloc& a,
               pair<U1, U2>&&);                           // (18) C++17
template <class Alloc, class U1, class U2>
explicit(see below) constexpr
  tuple(allocator_arg_t,
        const Alloc& a,
        pair<U1, U2>&&);                                  // (18) C++20

tupleオブジェクトの構築

  • (1) : すべての要素を初期化して構築
  • (2) : 可変テンプレートパラメータの型の値によるコピー構築
  • (3) : 可変テンプレートパラメータの型に変換可能な値によるムーブ構築
  • (4) : コピーコンストラクタ
  • (5) : ムーブコンストラクタ
  • (6) : 変換可能な型からのコピーコンストラクタ
  • (7) : 変換可能な型からのムーブコンストラクタ
  • (8) : テンプレートパラメータ数が2の場合に、std::pairオブジェクトからコピー構築する
  • (9) : テンプレートパラメータ数が2の場合に、std::pairオブジェクトからムーブ構築する
  • (10) : アロケータを指定してデフォルト構築する
  • (11) : アロケータを指定して可変テンプレートパラメータの型の値によってコピー構築する
  • (12) : アロケータを指定して可変テンプレートパラメータの型の値によってムーブ構築する
  • (13) : アロケータを指定してコピー構築
  • (14) : アロケータを指定してムーブ構築
  • (15) : アロケータを指定して変換可能な他のtupleオブジェクトからコピー構築
  • (16) : アロケータを指定して変換可能な他のtupleオブジェクトからムーブ構築
  • (17) : テンプレートパラメータ数が2の場合、アロケータを指定してstd::pairオブジェクトからコピー構築する
  • (18) : テンプレートパラメータ数が2の場合、アロケータを指定してstd::pairオブジェクトからムーブ構築する

テンプレートパラメータ制約

  • (1), (10) :
  • (2), (11) :
  • (3), (12) :
    • sizeof...(Types) == sizeof...(UTypes)であること
    • C++17 : sizeof...(Types) >= 1であること
    • Types...の全ての型Tiと、UTypes...の全ての型Uiについて、is_constructible<Ti, Ui&&>::value == trueであること
  • (4), (13) :
  • (5), (14) :
  • (6), (15) :
    • sizeof...(Types) == sizeof...(UTypes)であること
    • Types...の全ての型Tiと、UTypes...の全ての型Uiについて、is_constructible<Ti, const Ui&>::value == trueであること
    • C++17 : sizeof(Types...) != 1であるか、そうでなければTypes...の先頭をTUTypes...の先頭をUとして、!is_convertible_v<const tuple<U>&, T> && !is_constructible_v<T, const tuple<U>&> && !is_same_v<T, U>trueであること
      • コピーコンストラクタとのオーバーロードが成立することを意図している
  • (7), (16) :
    • sizeof...(Types) == sizeof...(UTypes)であること
    • Types...の全ての型Tiと、UTypes...の全ての型Uiについて、is_constructible<Ti, Ui&&>::value == trueであること
    • C++17 : sizeof(Types...) != 1であるか、そうでなければTypes...の先頭をTUTypes...の先頭をUとして、!is_convertible_v<tuple<U>, T> && !is_constructible_v<T, tuple<U>> && !is_same_v<T, U>trueであること
      • ムーブコンストラクタとのオーバーロードが成立することを意図している
  • (8), (17) :
    • Types...の0番目の型をT0、1番目の型をT1であるとする
    • sizeof...(Types) == 2であること
    • is_constructible<T0, const U1&>::value == trueかつis_constructible<T1, const U2&>::value == trueであること
  • (9), (18) :
    • Types...の0番目の型をT0、1番目の型をT1であるとする
    • sizeof...(Types) == 2であること
    • is_constructible<T0, U1&&>::value == trueかつis_constructible<T1, U2&&>::value == trueであること

備考

  • (1) :
    • C++17 : Types...のうちいずれかの型が非暗黙にデフォルト構築できる場合、この関数はexplicitとなる
  • (2) :
    • C++11からC++14まで : 無条件でexplicitとなる
    • C++17から : !conjunction_v<is_convertible<const Types&, Types>...>である場合、この関数はexplicitとなる
  • (3) :
    • C++11からC++14まで : 無条件でexplicitとなる
    • C++17から : !conjunction_v<is_convertible<UTypes, Types>...>である場合、この関数はexplicitとなる
  • (6) :
  • (7) :
  • (8) :
    • Types...の0番目の型をT0、1番目の型をT1であるとする
    • !is_convertible_v<U1, T0> || !is_convertible_v<U2, T1>である場合、この関数はexplicitとなる
  • (11) :
    • C++17 : (2)と同じ条件でexplicitとなる
  • (12) :
    • C++17 : (3)と同じ条件でexplicitとなる
  • (15) :
    • C++17 : (6)と同じ条件でexplicitとなる
  • (16) :
    • C++17 : (7)と同じ条件でexplicitとなる
  • (17) :
    • C++17 : (8)と同じ条件でexplicitとなる
  • (18) :
    • C++17 : (9)と同じ条件でexplicitとなる
  • C++17では、コンストラクタの各オーバーロードが条件付きでexplicitとなるよう規定された。これは、以下のような初期化子リストを使用したC++17での初期化が不適格になっていたため、適格になるようにするための変更である:

    std::tuple<int, int> pixel_coordinates()
    {
      return {10, -15};  // C++14でコンパイルエラー!
    }
    
    struct NonCopyable { NonCopyable(int); NonCopyable(const NonCopyable&) = delete; };
    std::pair<NonCopyable, double> pmd{42, 3.14};  // C++14でコンパイルエラー!
    

    • この変更はC++17に対するものであるが、コンパイラが早期に対応していたため、一部処理系ではC++14の段階から適格となっていた

#include <tuple>
#include <string>
#include <utility>

int main()
{
  // デフォルトコンストラクト
  std::tuple<int, char, std::string> t1;

  // コピーコンストラクト
  std::tuple<int, char, std::string> t2(t1);

  // ムーブコンストラクト
  std::tuple<int, char, std::string> t3(std::move(t2));

  // 値を指定して構築
  std::tuple<int, char, std::string> t4(1, 'a', "hello");

  // pairから構築(2要素の場合のみ)
  std::tuple<int, char> t5 = std::make_pair(1, 'a');

  // アロケータを指定して構築。
  // std::allocator_argを第1引数にすると、第2引数がアロケータと見なされ、
  // 第3引数以降がtupleの要素となる
  std::tuple<int, char, std::string> t6(std::allocator_arg,
                                        std::allocator<std::tuple<int, char, std::string>>(),
                                        1, 'a', "hello");
}

出力

バージョン

言語

  • C++11

処理系

関連項目

参照