This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of CD1 status.
Section: 22.4.7 [tuple.helper] Status: CD1 Submitter: Alisdair Meredith Opened: 2008-01-16 Last modified: 2016-01-28
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 <intsize_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<intsize_t I, class T1, class T2>Ptypename tuple_element<I, std::pair<T1, T2> >::type & get(std::pair<T1, T2>&); template<intsize_t I, class T1, class T2> constPtypename tuple_element<I, std::pair<T1, T2> >::type & get(const std::pair<T1, T2>&);
Update 22.3 [pairs] Pairs
template<intsize_t I, class T1, class T2>Ptypename tuple_element<I, std::pair<T1, T2> >::type & get(pair<T1, T2>&); template<intsize_t I, class T1, class T2> constPtypename 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 <intsize_t I, class T> class tuple_element; // undefined template <intsize_t I, class... Types> class tuple_element<I, tuple<Types...> >; // 20.3.1.4, element access: template <intsize_t I, class... Types> typename tuple_element<I, tuple<Types...> >::type& get(tuple<Types...>&); template <intsize_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 <intsize_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 <intsize_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.
I
th element of t
, where indexing is zero-based.
Throws: Nothing.
template <intsize_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 declaration template <intsize_t I, class T> class tuple_element; // forward declaration template <class T, size_t N> struct tuple_size<array<T, N> >; template <intsize_t I, class T, size_t N> struct tuple_element<I, array<T, N> >; template <intsize_t I, class T, size_t N> T& get(array<T, N>&); template <intsize_t I, class T, size_t N> const T& get(const array<T, N>&);
Update 23.3.3.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 <intsize_t I, class T, size_t N> T& get(array<T, N>& a);
5 Requires:
. The program is ill-formed if 0 <= I < NI
is out of bounds.
Returns: A reference to the I
th element of a
, where indexing is zero-based.
Throws: Nothing.
template <intsize_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 < NI
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. ]