如何使用std::rotate来旋转第一个成员为const的pair数组?
How can I use std::rotate to rotate an array of pairs whose first member is const?
我正在实现一个映射,并且我想在一对数组上使用std::rotate,其中第一个成员是const(因此在插入映射时不能更改键)。它相当于下面不能编译的代码:
#include <utility>
#include <array>
#include <algorithm>
int main()
{
typedef std::pair<const int, int> map_entry;
std::array<map_entry, 3> a{ { {2, 0}, {1, 0}, {3, 0} } };
std::rotate(&a[0], &a[1], &a[3]);
}
不幸的是,我无法控制pair的类型("value_type"),它需要定义如下:与std::unordered_map:
兼容 template <class K, class T, class H, class P, class A>
class unordered_map
{
public:
typedef K key_type;
typedef std::pair<const K, T> value_type;
typedef T mapped_type;
是否有办法让我使用std::旋转这样一个数组,也许通过删除const的某种方式?
下面是编译错误:
$ g++ -std=c++11 xx.cxx
In file included from /usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/utility:70:0,
from xx.cxx:1:
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_pair.h: In instantiation of ‘std::pair<_T1, _T2>& std::pair<_T1, _T2>::operator=(std::pair<_T1 , _T2>&&) [with _T1 = const int; _T2 = int]’:
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_algo.h:1610:22: required from ‘void std::__rotate(_RandomAccessIterator, _RandomAccessIterat or, _RandomAccessIterator, std::random_access_iterator_tag) [with _RandomAccessIterator = std::pair<const int, int>*]’
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_algo.h:1686:59: required from ‘void std::rotate(_FIter, _FIter, _FIter) [with _FIter = std:: pair<const int, int>*]’
xx.cxx:9:36: required from here
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_pair.h:170:8: error: assignment of read-only member ‘std::pair<const int, int>::first’
first = std::forward<first_type>(__p.first);
^
In file included from /usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_pair.h:59:0,
from /usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/utility:70,
from xx.cxx:1:
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/move.h: In instantiation of ‘void std::swap(_Tp&, _Tp&) [with _Tp = const int]’:
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_pair.h:199:23: required from ‘void std::pair<_T1, _T2>::swap(std::pair<_T1, _T2>&) [with _T1 = const int; _T2 = int]’
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_pair.h:256:7: required from ‘void std::swap(std::pair<_T1, _T2>&, std::pair<_T1, _T2>&) [wit h _T1 = const int; _T2 = int]’
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_algobase.h:147:22: required from ‘void std::iter_swap(_ForwardIterator1, _ForwardIterator2) [with _ForwardIterator1 = std::pair<const int, int>*; _ForwardIterator2 = std::pair<const int, int>*]’
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_algo.h:1616:28: required from ‘void std::__rotate(_RandomAccessIterator, _RandomAccessIterat or, _RandomAccessIterator, std::random_access_iterator_tag) [with _RandomAccessIterator = std::pair<const int, int>*]’
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_algo.h:1686:59: required from ‘void std::rotate(_FIter, _FIter, _FIter) [with _FIter = std:: pair<const int, int>*]’
xx.cxx:9:36: required from here
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/move.h:176:11: error: assignment of read-only reference ‘__a’
__a = _GLIBCXX_MOVE(__b);
^
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/move.h:177:11: error: assignment of read-only reference ‘__b’
__b = _GLIBCXX_MOVE(__tmp);
^
简单:不要使用std::pair
。设计一个具有所需语义的类并使用它。特别是,不要使数据成员为const。相反,将它们设为私有并编写访问器来强制const-ness。int first() const;
, int second() const;
和int& second();
是一个很好的开始。但它们真的应该被命名为key()
和value()
,或者其他更符合你的设计的名字。
我找到了解决办法。在内部,我存储了没有const (mutable_value_type)的值对,但是我仍然用const定义了value_type,这就是当你解引用迭代器时返回的值。
template <class K, class T, class H, class P, class A>
class unordered_map
{
public:
typedef K key_type;
typedef std::pair<const K, T> value_type;
typedef std::pair<K, T> mutable_value_type;