如何使用std :: rotate来旋转第一个成员为const的对数组?

时间:2016-07-04 00:25:39

标签: c++ stl

我正在实现一个map,我想在一对数组上使用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]);
}

不幸的是,我无法控制需要定义的对的类型(“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 :: rotate,也许是以某种方式删除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);
           ^

2 个答案:

答案 0 :(得分:0)

简单:不要使用std::pair。设计一个具有您需要的语义并使用它的类。特别是,不要使数据成员为const。相反,将它们设为私有,并编写访问器以强制执行常量。 int first() const;int second() const;int& second();是个不错的开始。但它们确实应该被命名为key()value(),或者更符合您设计的其他内容。

答案 1 :(得分:0)

我找到了解决方案。在内部,我存储了没有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;