Files
2025-10-25 03:02:53 +03:00

407 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.6The 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<Ti> 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<Ti> 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<Ti> 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<is_convertible<const Types&, Types>...>
[🔗](#lib:tuple,constructor__)
`template<class... UTypes> 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<is_same<remove_cvref_t<U0>, tuple>> if sizeof...(Types) is 1;
- [(12.2)](#12.2)
otherwise,bool_constant<!is_same_v<remove_cvref_t<U0>, allocator_arg_t> || is_-
same_v<remove_cvref_t<T0>, 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<Types, UTypes>...> 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<UTypes>(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<is_convertible<UTypes, Types>...>
This constructor is defined as deleted if(reference_constructs_from_temporary_v<Types, UTypes&&> || ...) 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<Ti> 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<Ti> 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<Ti>(get<i>(u))[.](#19.sentence-1)
[🔗](#lib:tuple,constructor_____)
`template<class... UTypes> constexpr explicit(see below) tuple(tuple<UTypes...>& u);
template<class... UTypes> constexpr explicit(see below) tuple(const tuple<UTypes...>& u);
template<class... UTypes> constexpr explicit(see below) tuple(tuple<UTypes...>&& u);
template<class... UTypes> constexpr explicit(see below) tuple(const tuple<UTypes...>&& 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<decltype(u)>(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<Types, decltype(get<I>(*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<decltype(u), T>,is_constructible_v<T, decltype(u)>, andis_same_v<T, U> 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<i>(*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<decltype(get<I>(*FWD*(u))), Types> && ...)
The constructor is defined as deleted if(reference_constructs_from_temporary_v<Types, decltype(get<I>(*FWD*(u)))> || ...) is true[.](#23.sentence-2)
[🔗](#lib:tuple,constructor______)
`template<class U1, class U2> constexpr explicit(see below) tuple(pair<U1, U2>& u);
template<class U1, class U2> constexpr explicit(see below) tuple(const pair<U1, U2>& u);
template<class U1, class U2> constexpr explicit(see below) tuple(pair<U1, U2>&& u);
template<class U1, class U2> constexpr explicit(see below) tuple(const pair<U1, U2>&& u);
`
[24](#24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2004)
Let *FWD*(u) be static_cast<decltype(u)>(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<T0, decltype(get<0>(*FWD*(u)))> is true, and
- [(25.3)](#25.3)
is_constructible_v<T1, decltype(get<1>(*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<decltype(get<0>(*FWD*(u))), T0> ||!is_convertible_v<decltype(get<1>(*FWD*(u))), T1>
The constructor is defined as deleted ifreference_constructs_from_temporary_v<T0, decltype(get<0>(*FWD*(u)))> || reference_constructs_from_temporary_v<T1, decltype(get<1>(*FWD*(u)))> is true[.](#27.sentence-2)
[🔗](#lib:tuple,constructor_______)
`template<[tuple-like](tuple.like#concept:tuple-like "22.4.3Concept 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.2Helper concepts[range.utility.helpers]")<UTuple, tuple> ([[range.utility.helpers]](range.utility.helpers "25.5.2Helper concepts"))
is true,
- [(29.2)](#29.2)
remove_cvref_t<UTuple> is not a specialization of ranges::subrange,
- [(29.3)](#29.3)
sizeof...(Types) equals tuple_size_v<remove_cvref_t<UTuple>>,
- [(29.4)](#29.4)
(is_constructible_v<Types, decltype(get<I>(std::forward<UTuple>(u)))> && ...) istrue, and
- [(29.5)](#29.5)
either sizeof...(Types) is not 1, or
(when Types... expands to T)is_convertible_v<UTuple, T> andis_constructible_v<T, UTuple> 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<i>(std::forward<UTuple>(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<decltype(get<I>(std::forward<UTuple>(u))), Types> && ...)
The constructor is defined as deleted if(reference_constructs_from_temporary_v<Types, decltype(get<I>(std::forward<UTuple>(u)))>|| ...) is true[.](#31.sentence-2)
[🔗](#lib:tuple,constructor________)
`template<class Alloc>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a);
template<class Alloc>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, const Types&...);
template<class Alloc, class... UTypes>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, UTypes&&...);
template<class Alloc>
constexpr tuple(allocator_arg_t, const Alloc& a, const tuple&);
template<class Alloc>
constexpr tuple(allocator_arg_t, const Alloc& a, tuple&&);
template<class Alloc, class... UTypes>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&);
template<class Alloc, class... UTypes>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&);
template<class Alloc, class... UTypes>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&);
template<class Alloc, class... UTypes>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&&);
template<class Alloc, class U1, class U2>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&);
template<class Alloc, class U1, class U2>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
template<class Alloc, class U1, class U2>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
template<class Alloc, class U1, class U2>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&&);
template<class Alloc, [tuple-like](tuple.like#concept:tuple-like "22.4.3Concept tuple-like[tuple.like]") UTuple>
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.1General[allocator.requirements.general]") requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1General"))[.](#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.2Uses-allocator construction[allocator.uses.construction]")[.](#33.sentence-1)