I would like to swap parts of two maps using a standard algorithm, but somehow iterators on map do not seem to be swappable. I am surely missing something.
Example
#include<map>
#include<algorithm>
auto function(std::map<int,int> m1, std::map<int,int> m2)
{
auto first = m1.begin();
auto last = first;
std::advance(last, 3);
std::swap_ranges(first, last, m2.begin());
}
Error
See it on compiler explorer: https://godbolt.org/z/6bn1xYTTr
In file included from /opt/compiler-explorer/gcc-12.2.0/include/c /12.2.0/bits/stl_tree.h:63,
from /opt/compiler-explorer/gcc-12.2.0/include/c /12.2.0/map:60,
from <source>:1:
/opt/compiler-explorer/gcc-12.2.0/include/c /12.2.0/bits/stl_algobase.h: In instantiation of 'void std::iter_swap(_ForwardIterator1, _ForwardIterator2) [with _ForwardIterator1 = _Rb_tree_iterator<pair<const int, int> >; _ForwardIterator2 = _Rb_tree_iterator<pair<const int, int> >]':
/opt/compiler-explorer/gcc-12.2.0/include/c /12.2.0/bits/stl_algobase.h:212:16: required from '_ForwardIterator2 std::swap_ranges(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2) [with _ForwardIterator1 = _Rb_tree_iterator<pair<const int, int> >; _ForwardIterator2 = _Rb_tree_iterator<pair<const int, int> >]'
<source>:9:21: required from here
/opt/compiler-explorer/gcc-12.2.0/include/c /12.2.0/bits/stl_algobase.h:182:11: error: use of deleted function 'typename std::enable_if<(! std::__and_<std::__is_swappable<_T1>, std::__is_swappable<_T2> >::value)>::type std::swap(pair<_T1, _T2>&, pair<_T1, _T2>&) [with _T1 = const int; _T2 = int; typename enable_if<(! __and_<__is_swappable<_T1>, __is_swappable<_T2> >::value)>::type = void]'
182 | swap(*__a, *__b);
| ~~~~^~~~~~~~~~~~
In file included from /opt/compiler-explorer/gcc-12.2.0/include/c /12.2.0/bits/stl_algobase.h:64:
/opt/compiler-explorer/gcc-12.2.0/include/c /12.2.0/bits/stl_pair.h:715:5: note: declared here
715 | swap(pair<_T1, _T2>&, pair<_T1, _T2>&) = delete;
| ^~~~
Compiler returned: 1
CodePudding user response:
std::map
is implemented as some sort of binary search tree, and its structure depends on each item's key never changing. Thus the type returned by *m1.begin()
is std::pair<const int, int>&
. Note that the first int
is const
. You cannot modify it.
std::swap_ranges
tries to swap each element of the first range with its corresponding element in the second range, but std::pair<const int, int>
s can't be swap
ped due to the const
ness of their first element.