list::splice
functionSection: 23.3.9.5 [list.ops], 23.3.7.6 [forward.list.ops] Status: NAD Submitter: Arseny Klimovsky Opened: 2013-08-15 Last modified: 2023-02-07
Priority: Not Prioritized
View all other issues in [list.ops].
View all issues with NAD status.
Discussion:
I think that the effects of list::splice
function should be stated more carefully.
void splice(const_iterator position, list& x, const_iterator i); void splice(const_iterator position, list&& x, const_iterator i);Effects: Inserts an element pointed to by
i
from listx
before position and removes the element fromx
. The result is unchanged ifposition == i
orposition == ++i
. Pointers and references to*i
continue to refer to this same element but as a member of*this
. Iterators to*i
(includingi
itself) continue to refer to the same element, but now behave as iterators into*this
, not intox
.
But it is incorrect to talk about operator==
for iterators that are not from the same container (after acceptance of
N3066, 24.3.5.5 [forward.iterators] p2).
So, the text operates with an undefined behaviour.
One is formally allowed to have list implementation where two iterators from different lists return true to operator==
.
For example, this can only happen to non-dereferenceable iterators, and position
and ++i
can be
non-dereferenceable. So, literally according to the standard, it is not allowed in this implementation to transfer
such elements with splice
function.
[2013-09 Chicago (late night issues)]
Moved to NAD.
The condition under which the list
is unchanged is not program code, so there is no undefined behavior to protect against.
Rather, the precondition that the evaluation can be performed is implicit if determining when the condition applies.
Proposed resolution:
This wording is relative to N3691.
Modify [forwardlist.ops] p6 as indicated:
void splice_after(const_iterator position, forward_list& x, const_iterator i); void splice_after(const_iterator position, forward_list&& x, const_iterator i);[…]
-6- Effects: Inserts the element followingi
into*this
, followingposition
, and removes it fromx
. The result is unchanged if&x == this
and the following condition is satisfied:position == i
orposition == ++i
. Pointers and references to*++i
continue to refer to the same element but as a member of*this
. Iterators to*++i
continue to refer to the same element, but now behave as iterators into*this
, not intox
.
Modify 23.3.9.5 [list.ops] p7 as indicated:
void splice(const_iterator position, list& x, const_iterator i); void splice(const_iterator position, list&& x, const_iterator i);-7- Effects: Inserts an element pointed to by
i
from listx
before position and removes the element fromx
. The result is unchanged if&x == this
and the following condition is satisfied:position == i
orposition == ++i
. Pointers and references to*i
continue to refer to this same element but as a member of*this
. Iterators to*i
(includingi
itself) continue to refer to the same element, but now behave as iterators into*this
, not intox
.