[tuple.cnstr] # 22 General utilities library [[utilities]](./#utilities) ## 22.4 Tuples [[tuple]](tuple#cnstr) ### 22.4.4 Class template tuple [[tuple.tuple]](tuple.tuple#tuple.cnstr) #### 22.4.4.2 Construction [tuple.cnstr] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1788) In the descriptions that follow, let i be in the range [0, sizeof...(Types)) in order, Ti be the ith type in Types, andUi be the ith type in a template parameter pack named UTypes, where indexing is zero-based[.](#1.sentence-1) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1795) For each tuple constructor, an exception is thrown only if the construction of one of the types in Types throws an exception[.](#2.sentence-1) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1799) The defaulted move and copy constructor, respectively, oftuple is a constexpr function if and only if all required element-wise initializations for move and copy, respectively, would be constexpr-suitable ([[dcl.constexpr]](dcl.constexpr "9.2.6 The constexpr and consteval specifiers"))[.](#3.sentence-1) The defaulted move and copy constructor of tuple<> are constexpr functions[.](#3.sentence-2) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1807) If is_trivially_destructible_v is true for all Ti, then the destructor of tuple is trivial[.](#4.sentence-1) [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1811) The default constructor of tuple<> is trivial[.](#5.sentence-1) [🔗](#lib:tuple,constructor) `constexpr explicit(see below) tuple(); ` [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1820) *Constraints*: is_default_constructible_v is true for all i[.](#6.sentence-1) [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1824) *Effects*: Value-initializes each element[.](#7.sentence-1) [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1828) *Remarks*: The expression inside explicit evaluates to true if and only if Ti is not copy-list-initializable from an empty list for at least one i[.](#8.sentence-1) [*Note [1](#note-1)*: This behavior can be implemented with a trait that checks whether a const Ti& can be initialized with {}[.](#8.sentence-2) — *end note*] [🔗](#lib:tuple,constructor_) `constexpr explicit(see below) tuple(const Types&...); ` [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1846) *Constraints*: sizeof...(Types) ≥ 1 andis_copy_constructible_v is true for all i[.](#9.sentence-1) [10](#10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1851) *Effects*: Initializes each element with the value of the corresponding parameter[.](#10.sentence-1) [11](#11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1856) *Remarks*: The expression inside explicit is equivalent to:!conjunction_v...> [🔗](#lib:tuple,constructor__) `template constexpr explicit(see below) tuple(UTypes&&... u); ` [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1870) Let *disambiguating-constraint* be: - [(12.1)](#12.1) negation, tuple>> if sizeof...(Types) is 1; - [(12.2)](#12.2) otherwise,bool_constant, allocator_arg_t> || is_- same_v, allocator_arg_t>> if sizeof...(Types) is 2 or 3; - [(12.3)](#12.3) otherwise, true_type[.](#12.sentence-1) [13](#13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1885) *Constraints*: - [(13.1)](#13.1) sizeof...(Types) equals sizeof...(UTypes), - [(13.2)](#13.2) sizeof...(Types) ≥ 1, and - [(13.3)](#13.3) conjunction_v<*disambiguating-constraint*, is_constructible...> is true[.](#13.sentence-1) [14](#14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1897) *Effects*: Initializes the elements in the tuple with the corresponding value in std​::​forward(u)[.](#14.sentence-1) [15](#15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1902) *Remarks*: The expression inside explicit is equivalent to:!conjunction_v...> This constructor is defined as deleted if(reference_constructs_from_temporary_v || ...) is true[.](#15.sentence-2) [🔗](#lib:tuple,constructor___) `tuple(const tuple& u) = default; ` [16](#16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1921) *Mandates*: is_copy_constructible_v is true for all i[.](#16.sentence-1) [17](#17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1925) *Effects*: Initializes each element of *this with the corresponding element of u[.](#17.sentence-1) [🔗](#lib:tuple,constructor____) `tuple(tuple&& u) = default; ` [18](#18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1937) *Constraints*: is_move_constructible_v is true for all i[.](#18.sentence-1) [19](#19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1941) *Effects*: For all i, initializes the ith element of *this withstd​::​forward(get(u))[.](#19.sentence-1) [🔗](#lib:tuple,constructor_____) `template constexpr explicit(see below) tuple(tuple& u); template constexpr explicit(see below) tuple(const tuple& u); template constexpr explicit(see below) tuple(tuple&& u); template constexpr explicit(see below) tuple(const tuple&& u); ` [20](#20) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1956) Let I be the pack 0, 1, …, (sizeof...(Types) - 1)[.](#20.sentence-1) Let *FWD*(u) be static_cast(u)[.](#20.sentence-2) [21](#21) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1960) *Constraints*: - [(21.1)](#21.1) sizeof...(Types) equals sizeof...(UTypes), and - [(21.2)](#21.2) (is_constructible_v(*FWD*(u)))> && ...) is true, and - [(21.3)](#21.3) either sizeof...(Types) is not 1, or (when Types... expands to T andUTypes... expands to U)is_convertible_v,is_constructible_v, andis_same_v are all false[.](#21.sentence-1) [22](#22) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1977) *Effects*: For all i, initializes the ith element of *this with get(*FWD*(u))[.](#22.sentence-1) [23](#23) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1982) *Remarks*: The expression inside explicit is equivalent to:!(is_convertible_v(*FWD*(u))), Types> && ...) The constructor is defined as deleted if(reference_constructs_from_temporary_v(*FWD*(u)))> || ...) is true[.](#23.sentence-2) [🔗](#lib:tuple,constructor______) `template constexpr explicit(see below) tuple(pair& u); template constexpr explicit(see below) tuple(const pair& u); template constexpr explicit(see below) tuple(pair&& u); template constexpr explicit(see below) tuple(const pair&& u); ` [24](#24) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2004) Let *FWD*(u) be static_cast(u)[.](#24.sentence-1) [25](#25) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2007) *Constraints*: - [(25.1)](#25.1) sizeof...(Types) is 2, - [(25.2)](#25.2) is_constructible_v(*FWD*(u)))> is true, and - [(25.3)](#25.3) is_constructible_v(*FWD*(u)))> is true[.](#25.sentence-1) [26](#26) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2018) *Effects*: Initializes the first element with get<0>(*FWD*(u)) and the second element with get<1>(*FWD*(​u))[.](#26.sentence-1) [27](#27) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2023) *Remarks*: The expression inside explicit is equivalent to:!is_convertible_v(*FWD*(u))), T0> ||!is_convertible_v(*FWD*(u))), T1> The constructor is defined as deleted ifreference_constructs_from_temporary_v(*FWD*(u)))> || reference_constructs_from_temporary_v(*FWD*(u)))> is true[.](#27.sentence-2) [🔗](#lib:tuple,constructor_______) `template<[tuple-like](tuple.like#concept:tuple-like "22.4.3 Concept tuple-like [tuple.like]") UTuple> constexpr explicit(see below) tuple(UTuple&& u); ` [28](#28) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2045) Let I be the pack 0, 1, …, (sizeof...(Types) - 1)[.](#28.sentence-1) [29](#29) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2048) *Constraints*: - [(29.1)](#29.1) [*different-from*](range.utility.helpers#concept:different-from "25.5.2 Helper concepts [range.utility.helpers]") ([[range.utility.helpers]](range.utility.helpers "25.5.2 Helper concepts")) is true, - [(29.2)](#29.2) remove_cvref_t is not a specialization of ranges​::​subrange, - [(29.3)](#29.3) sizeof...(Types) equals tuple_size_v>, - [(29.4)](#29.4) (is_constructible_v(std​::​forward(u)))> && ...) istrue, and - [(29.5)](#29.5) either sizeof...(Types) is not 1, or (when Types... expands to T)is_convertible_v andis_constructible_v are both false[.](#29.sentence-1) [30](#30) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2075) *Effects*: For all i, initializes the ith element of *this withget(std​::​forward(u))[.](#30.sentence-1) [31](#31) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2080) *Remarks*: The expression inside explicit is equivalent to:!(is_convertible_v(std::forward(u))), Types> && ...) The constructor is defined as deleted if(reference_constructs_from_temporary_v(std::forward(u)))>|| ...) is true[.](#31.sentence-2) [🔗](#lib:tuple,constructor________) `template constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a); template constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const Types&...); template constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, UTypes&&...); template constexpr tuple(allocator_arg_t, const Alloc& a, const tuple&); template constexpr tuple(allocator_arg_t, const Alloc& a, tuple&&); template constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, tuple&); template constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const tuple&); template constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, tuple&&); template constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const tuple&&); template constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, pair&); template constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const pair&); template constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, pair&&); template constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const pair&&); template constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, UTuple&&); ` [32](#32) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2139) *Preconditions*: Alloc meets the [*Cpp17Allocator*](allocator.requirements.general#:Cpp17Allocator "16.4.4.6.1 General [allocator.requirements.general]") requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1 General"))[.](#32.sentence-1) [33](#33) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2144) *Effects*: Equivalent to the preceding constructors except that each element is constructed with[uses-allocator construction](allocator.uses.construction#def:uses-allocator_construction "20.2.8.2 Uses-allocator construction [allocator.uses.construction]")[.](#33.sentence-1)