This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++11 status.
Section: 23.3.7.6 [forward.list.ops], 23.3.9.5 [list.ops] Status: C++11 Submitter: Alisdair Meredith Opened: 2009-05-09 Last modified: 2023-02-07
Priority: Not Prioritized
View all other issues in [forward.list.ops].
View all issues with C++11 status.
Discussion:
IIUC,
N2844
means that lvalues will no longer bind to rvalue references.
Therefore, the current specification of list::splice
(list
operations 23.3.9.5 [list.ops]) will be a breaking change of behaviour for existing
programs. That is because we changed the signature to swallow via an rvalue
reference rather than the lvalue reference used in 03.
Retaining this form would be safer, requiring an explicit move when splicing
from lvalues. However, this will break existing programs.
We have the same problem with forward_list
, although without the risk of
breaking programs so here it might be viewed as a positive feature.
The problem signatures:
void splice_after(const_iterator position, forward_list<T,Alloc>&& x); void splice_after(const_iterator position, forward_list<T,Alloc>&& x, const_iterator i); void splice_after(const_iterator position, forward_list<T,Alloc>&& x, const_iterator first, const_iterator last); void splice(const_iterator position, list<T,Alloc>&& x); void splice(const_iterator position, list<T,Alloc>&& x, const_iterator i); void splice(const_iterator position, list<T,Alloc>&& x, const_iterator first, const_iterator last);
Possible resolutions:
Option A. Add an additional (non-const) lvalue-reference overload in each case
Option B. Change rvalue reference back to (non-const) lvalue-reference overload in each case
Option C. Add an additional (non-const) lvalue-reference
overload in just the std::list
cases
I think (B) would be very unfortunate, I really like the forward_list
behaviour in (C) but feel (A) is needed for consistency.
My actual preference would be NAD, ship with this as a breaking change as it is a more explicit interface. I don't think that will fly though!
See the thread starting with c++std-lib-23725 for more discussion.
[ 2009-10-27 Christopher Jefferson provides proposed wording for Option C. ]
[ 2009-12-08 Jonathan Wakely adds: ]
As Bill Plauger pointed out,
list::merge
needs similar treatment.[ Wording updated. ]
[ 2009-12-13 Moved to Tentatively Ready after 5 positive votes on c++std-lib. ]
Proposed resolution:
In 23.3.9 [list]
Add lvalue overloads before rvalue ones:
void splice(const_iterator position, list<T,Allocator>& x); void splice(const_iterator position, list<T,Allocator>&& x); void splice(const_iterator position, list<T,Allocator>& x, const_iterator i); void splice(const_iterator position, list<T,Allocator>&& x, const_iterator i); void splice(const_iterator position, list<T,Allocator>& x, const_iterator first, const_iterator last); void splice(const_iterator position, list<T,Allocator>&& x, const_iterator first, const_iterator last); void merge(list<T,Allocator>& x); template <class Compare> void merge(list<T,Allocator>& x, Compare comp); void merge(list<T,Allocator>&& x); template <class Compare> void merge(list<T,Allocator>&& x, Compare comp);
In 23.3.9.5 [list.ops], similarly add lvalue overload before each rvalue one:
(After paragraph 2)
void splice(const_iterator position, list<T,Allocator>& x); void splice(const_iterator position, list<T,Allocator>&& x);
(After paragraph 6)
void splice(const_iterator position, list<T,Allocator>& x, const_iterator i); void splice(const_iterator position, list<T,Allocator>&& x, const_iterator i);
(After paragraph 10)
void splice(const_iterator position, list<T,Allocator>& x, const_iterator first, const_iterator last); void splice(const_iterator position, list<T,Allocator>&& x, const_iterator first, const_iterator last);
In 23.3.9.5 [list.ops], after paragraph 21
void merge(list<T,Allocator>& x); template <class Compare> void merge(list<T,Allocator>& x, Compare comp); void merge(list<T,Allocator>&& x); template <class Compare> void merge(list<T,Allocator>&& x, Compare comp);