[tuple.elem]

# 22 General utilities library [[utilities]](./#utilities)

## 22.4 Tuples [[tuple]](tuple#elem)

### 22.4.8 Element access [tuple.elem]

[ð](#lib:get,tuple)

`template<size_t I, class... Types>
  constexpr tuple_element_t<I, tuple<Types...>>&
    get(tuple<Types...>& t) noexcept;
template<size_t I, class... Types>
  constexpr tuple_element_t<I, tuple<Types...>>&&
    get(tuple<Types...>&& t) noexcept;        // #1
template<size_t I, class... Types>
  constexpr const tuple_element_t<I, tuple<Types...>>&
    get(const tuple<Types...>& t) noexcept;   // #2
template<size_t I, class... Types>
  constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&& t) noexcept;
`

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2873)

*Mandates*: I < sizeof...(Types)[.](#1.sentence-1)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2877)

*Returns*: A reference to the Ith element of t, where
indexing is zero-based[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2882)

[*Note [1](#note-1)*:

For the overload marked #1,
if a type T in Types is some reference type X&,
the return type is X&, not X&&[.](#3.sentence-1)

However, if the element type is a non-reference type T,
the return type is T&&[.](#3.sentence-2)

â *end note*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2891)

[*Note [2](#note-2)*:

Constness is shallow[.](#4.sentence-1)

For the overload marked #2,
if a type T in Types is some reference type X&,
the return type is X&, not const X&[.](#4.sentence-2)

However, if the element type is a non-reference type T,
the return type is const T&[.](#4.sentence-3)

This is consistent with how constness is defined to work
for non-static data members of reference type[.](#4.sentence-4)

â *end note*]

[ð](#lib:get,tuple_)

`template<class T, class... Types>
  constexpr T& get(tuple<Types...>& t) noexcept;
template<class T, class... Types>
  constexpr T&& get(tuple<Types...>&& t) noexcept;
template<class T, class... Types>
  constexpr const T& get(const tuple<Types...>& t) noexcept;
template<class T, class... Types>
  constexpr const T&& get(const tuple<Types...>&& t) noexcept;
`

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2917)

*Mandates*: The type T occurs exactly once in Types[.](#5.sentence-1)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2921)

*Returns*: A reference to the element of t corresponding to the typeT in Types[.](#6.sentence-1)

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2926)

[*Example [1](#example-1)*: const tuple<int, const int, double, double> t(1, 2, 3.4, 5.6);const int& i1 = get<int>(t); // OK, i1 has value 1const int& i2 = get<const int>(t); // OK, i2 has value 2const double& d = get<double>(t); // error: type double is not unique within t â *end example*]

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L2937)

[*Note [3](#note-3)*:

The reason get is a
non-member function is that if this functionality had been
provided as a member function, code where the type
depended on a template parameter would have required using
the template keyword[.](#8.sentence-1)

â *end note*]
