1191. tuple get API should respect rvalues

Section: 22.4.8 [tuple.elem] Status: C++11 Submitter: Alisdair Meredith Opened: 2009-08-18 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [tuple.elem].

View all issues with C++11 status.

Discussion:

The tuple get API should respect rvalues. This would allow for moving a single element out of a tuple-like type.

[ 2009-10-30 Alisdair adds: ]

The issue of rvalue overloads of get for tuple-like types was briefly discussed in Santa Cruz.

The feedback was this would be welcome, but we need full wording for the other types (pair and array) before advancing.

I suggest the issue moves to Open from New as it has been considered, feedback given, and it has not (yet) been rejected as NAD.

[ 2010 Rapperswil: ]

Note that wording has been provided, and this issue becomes more important now that we have added a function to support forwarding argument lists as tuples. Move to Tentatively Ready.

[ Adopted at 2010-11 Batavia ]

Proposed resolution:

Add the following signature to p2 22.4.1 [tuple.general]


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

And again to 22.4.8 [tuple.elem].


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

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 non-reference type T, the return type is T&&. — end note]

Add the following signature to p1 22.2 [utility]


template <size_t I, class T1, class T2>
typename tuple_element<I, pair<T1,T2> >::type&& get(pair<T1, T2>&&);

And to p5 22.3.4 [pair.astuple]


template <size_t I, class T1, class T2>
typename tuple_element<I, pair<T1,T2> >::type&& get(pair<T1, T2>&& p);

Returns: If I == 0 returns std::forward<T1&&>(p.first); if I == 1 returns std::forward<T2&&>(p.second); otherwise the program is ill-formed.

Throws: Nothing.

Add the following signature to 23.3 [sequences] <array> synopsis

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

And after p8 23.3.3.7 [array.tuple]

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

Effects: Equivalent to return std::move(get<I>(a));