**Section:** 22.4.7 [tuple.helper] **Status:** CD1
**Submitter:** Alisdair Meredith **Opened:** 2008-01-16 **Last modified:** 2016-01-28 10:19:27 UTC

**Priority: **Not Prioritized

**View all other** issues in [tuple.helper].

**View all issues with** CD1 status.

**Discussion:**

The tuple element access API identifies the element in the sequence
using signed integers, and then goes on to enforce the requirement that
I be >= 0. There is a much easier way to do this - declare I as
`unsigned`.

In fact the proposal is to use `std::size_t`

, matching the
type used in the `tuple_size` API.

A second suggestion is that it is hard to imagine an API that deduces
and index at compile time and returns a reference throwing an exception.
Add a specific *Throws:* Nothing paragraph to each element
access API.

In addition to `tuple`

, update the API applies to
`pair`

and `array`

, and should be updated
accordingly.

A third observation is that the return type of the `get`

functions for `std::pair`

is pseudo-code, but it is not
clearly marked as such. There is actually no need for pseudo-code as
the return type can be specified precisely with a call to
`tuple_element`

. This is already done for
`std::tuple`

, and `std::array`

does not have a
problem as all elements are of type `T`

.

**Proposed resolution:**

Update header <utility> synopsis in 22.2 [utility]

// 20.2.3, tuple-like access to pair:template <class T> class tuple_size; template <~~int~~size_t I, class T> class tuple_element; template <class T1, class T2> struct tuple_size<std::pair<T1, T2> >; template <class T1, class T2> struct tuple_element<0, std::pair<T1, T2> >; template <class T1, class T2> struct tuple_element<1, std::pair<T1, T2> >; template<~~int~~size_t I, class T1, class T2>~~P~~typename tuple_element<I, std::pair<T1, T2> >::type & get(std::pair<T1, T2>&); template<~~int~~size_t I, class T1, class T2> const~~P~~typename tuple_element<I, std::pair<T1, T2> >::type & get(const std::pair<T1, T2>&);

Update **22.3 [pairs] Pairs**

template<~~int~~size_t I, class T1, class T2>~~P~~typename tuple_element<I, std::pair<T1, T2> >::type & get(pair<T1, T2>&); template<~~int~~size_t I, class T1, class T2> const~~P~~typename tuple_element<I, std::pair<T1, T2> >::type & get(const pair<T1, T2>&);

~~24 ~~
*Return type:* If `I == 0`

then `P`

is `T1`

, if `I == 1`

then `P`

is `T2`

, and otherwise the program is ill-formed.

25 *Returns:* If `I == 0`

returns `p.first`

, ~~otherwise~~ if `I == 1`

returns `p.second`

, and otherwise the program is ill-formed.

*Throws:* Nothing.

Update header <tuple> synopsis in 22.4 [tuple] with a APIs as below:

template <~~int~~size_t I, class T> class tuple_element;// undefinedtemplate <~~int~~size_t I, class... Types> class tuple_element<I, tuple<Types...> >;// 20.3.1.4, element access:template <~~int~~size_t I, class... Types> typename tuple_element<I, tuple<Types...> >::type& get(tuple<Types...>&); template <~~int~~size_t I, class ... types> typename tuple_element<I, tuple<Types...> >::type const& get(const tuple<Types...>&);

Update **22.4.7 [tuple.helper] Tuple helper classes**

template <~~int~~size_t I, class... Types> class tuple_element<I, tuple<Types...> > { public: typedef TI type; };

1 *Requires:*

. The program is ill-formed if ~~0 <= I and ~~I < sizeof...(Types)`I`

is out of bounds.

2 *Type:* `TI`

is the type of the `I`

th element of `Types`

, where indexing is zero-based.

Update **22.4.8 [tuple.elem] Element access**

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

1 *Requires:*

. The program is ill-formed if ~~0 <= I and ~~I < sizeof...(Types)`I`

is out of bounds.

2 *Returns:* A reference to the `I`

th element of `t`

, where indexing is zero-based.

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

3 *Requires:*

. The program is ill-formed if ~~0 <= I and ~~I < sizeof...(Types)`I`

is out of bounds.

4 *Returns:* A const reference to the `I`

th element of `t`

, where indexing is zero-based.

*Throws:* Nothing.

Update header <array> synopsis in 22.2 [utility]

template <class T> class tuple_size;// forward declarationtemplate <~~int~~size_t I, class T> class tuple_element;// forward declarationtemplate <class T, size_t N> struct tuple_size<array<T, N> >; template <~~int~~size_t I, class T, size_t N> struct tuple_element<I, array<T, N> >; template <~~int~~size_t I, class T, size_t N> T& get(array<T, N>&); template <~~int~~size_t I, class T, size_t N> const T& get(const array<T, N>&);

Update **24.3.7.7 [array.tuple] Tuple interface to class template array**

tuple_element<size_t I, array<T, N> >::type

3 *Requires:*

The program is ill-formed if ~~0 <= ~~I < N.`I`

is out of bounds.

4 *Value:* The type `T`

.

template <~~int~~size_t I, class T, size_t N> T& get(array<T, N>& a);

5 *Requires:*

. The program is ill-formed if ~~0 <= ~~I < N`I`

is out of bounds.

*Returns:* A reference to the `I`

th element of `a`

, where indexing is zero-based.

*Throws:* Nothing.

template <~~int~~size_t I, class T, size_t N> const T& get(const array<T, N>& a);

6 *Requires:*

. The program is ill-formed if ~~0 <= ~~I < N`I`

is out of bounds.

7 *Returns:* A const reference to the `I`

th element of `a`

, where indexing is zero-based.

*Throws:* Nothing.

*[
Bellevue: Note also that the phrase "The program is ill-formed if I is
out of bounds" in the requires clauses are probably unnecessary, and
could be removed at the editor's discretion. Also std:: qualification
for pair is also unnecessary.
]*