```
template <size_t I, class... Types>
typename tuple_element<I, tuple<Types...> >::type& get(tuple<Types...>& t) noexcept;
```

*Requires:* I < sizeof...(Types).
The program is ill-formed if I is out of bounds.

*Returns:* A reference to the Ith element of t, where
indexing is zero-based.

```
template <size_t I, class... types>
typename tuple_element<I, tuple<Types...> >::type&& get(tuple<Types...>&& t) noexcept;
```

*Effects:* Equivalent to
return std::forward<typename tuple_element<I, tuple<Types...> >

::type&&>(get<I>(t));

*Note:* if a T in Types is some reference type X&, the return
type is X&, not X&&. However, if the element type is a non-reference type
T, the return type is T&&.

```
template <size_t I, class... Types>
typename tuple_element<I, tuple<Types...> >::type const& get(const tuple<Types...>& t) noexcept;
```

*Requires:* I < sizeof...(Types).
The program is ill-formed if I is out of bounds.

*Returns:* A const reference to the Ith element of t, where
indexing is zero-based.

[ *Note:* Constness is shallow. If a T
in Types is some
reference type X&, the return type is X&, not const X&.
However, if the element type is non-reference type T, the return
type is const T&.
This is consistent with how constness is defined to work
for member variables of reference type. * — end note* ]

[ *Note:* The reason get is a
nonmember 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. * — end note* ]