不能push_heap列表<int>,适用于矢量

时间:2017-02-16 22:08:10

标签: c++

我在push_heap上尝试list<int>,但编译失败抱怨列表迭代器。如果我将列表更改为矢量,它可以正常工作。

查看cpp引用我无法弄清楚为什么列表迭代器的行为会有所不同。也许有人可以解决一些问题?

https://ideone.com/pk5iJG

#include <algorithm>
#include <functional>
#include <list>

using namespace std;

int main() {

    list<int> l;
    l.push_back(0);
    push_heap(l.begin(), l.end(), greater<int>());
    return 0;
}

错误:

In file included from /usr/include/c++/6/bits/stl_pair.h:59:0,
                 from /usr/include/c++/6/utility:70,
                 from /usr/include/c++/6/algorithm:60,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_heap.h: In instantiation of ‘void std::push_heap(_RAIter, _RAIter, _Compare) [with _RAIter = std::_List_iterator<int>; _Compare = std::greater<int>]’:
prog.cpp:13:48:   required from here
/usr/include/c++/6/bits/stl_heap.h:200:28: error: no match for ‘operator-’ (operand types are ‘std::_List_iterator<int>’ and ‘int’)
       _ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
                            ^
In file included from /usr/include/c++/6/bits/stl_algobase.h:67:0,
                 from /usr/include/c++/6/algorithm:61,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_iterator.h:333:5: note: candidate: template<class _Iterator> decltype ((__x.base() - __y.base())) std::operator-(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
     operator-(const reverse_iterator<_Iterator>& __x,
     ^~~~~~~~
/usr/include/c++/6/bits/stl_iterator.h:333:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/6/bits/stl_pair.h:59:0,
                 from /usr/include/c++/6/utility:70,
                 from /usr/include/c++/6/algorithm:60,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_heap.h:200:28: note:   ‘std::_List_iterator<int>’ is not derived from ‘const std::reverse_iterator<_Iterator>’
       _ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
                            ^
In file included from /usr/include/c++/6/bits/stl_algobase.h:67:0,
                 from /usr/include/c++/6/algorithm:61,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_iterator.h:387:5: note: candidate: template<class _IteratorL, class _IteratorR> decltype ((__y.base() - __x.base())) std::operator-(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_IteratorR>&)
     operator-(const reverse_iterator<_IteratorL>& __x,
     ^~~~~~~~
/usr/include/c++/6/bits/stl_iterator.h:387:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/6/bits/stl_pair.h:59:0,
                 from /usr/include/c++/6/utility:70,
                 from /usr/include/c++/6/algorithm:60,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_heap.h:200:28: note:   ‘std::_List_iterator<int>’ is not derived from ‘const std::reverse_iterator<_Iterator>’
       _ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
                            ^
In file included from /usr/include/c++/6/bits/stl_algobase.h:67:0,
                 from /usr/include/c++/6/algorithm:61,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_iterator.h:1186:5: note: candidate: template<class _IteratorL, class _IteratorR> decltype ((__x.base() - __y.base())) std::operator-(const std::move_iterator<_IteratorL>&, const std::move_iterator<_IteratorR>&)
     operator-(const move_iterator<_IteratorL>& __x,
     ^~~~~~~~
/usr/include/c++/6/bits/stl_iterator.h:1186:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/6/bits/stl_pair.h:59:0,
                 from /usr/include/c++/6/utility:70,
                 from /usr/include/c++/6/algorithm:60,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_heap.h:200:28: note:   ‘std::_List_iterator<int>’ is not derived from ‘const std::move_iterator<_IteratorL>’
       _ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
                            ^
In file included from /usr/include/c++/6/bits/stl_algobase.h:67:0,
                 from /usr/include/c++/6/algorithm:61,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_iterator.h:1193:5: note: candidate: template<class _Iterator> decltype ((__x.base() - __y.base())) std::operator-(const std::move_iterator<_IteratorL>&, const std::move_iterator<_IteratorL>&)
     operator-(const move_iterator<_Iterator>& __x,
     ^~~~~~~~
/usr/include/c++/6/bits/stl_iterator.h:1193:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/6/bits/stl_pair.h:59:0,
                 from /usr/include/c++/6/utility:70,
                 from /usr/include/c++/6/algorithm:60,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_heap.h:200:28: note:   ‘std::_List_iterator<int>’ is not derived from ‘const std::move_iterator<_IteratorL>’
       _ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
                            ^
In file included from /usr/include/c++/6/bits/stl_algo.h:61:0,
                 from /usr/include/c++/6/algorithm:62,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_heap.h:201:55: error: no match for ‘operator-’ (operand types are ‘std::_List_iterator<int>’ and ‘std::_List_iterator<int>’)
       std::__push_heap(__first, _DistanceType((__last - __first) - 1),
                                               ~~~~~~~~^~~~~~~~~~
In file included from /usr/include/c++/6/bits/stl_algobase.h:67:0,
                 from /usr/include/c++/6/algorithm:61,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_iterator.h:333:5: note: candidate: template<class _Iterator> decltype ((__x.base() - __y.base())) std::operator-(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
     operator-(const reverse_iterator<_Iterator>& __x,
     ^~~~~~~~
/usr/include/c++/6/bits/stl_iterator.h:333:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/6/bits/stl_algo.h:61:0,
                 from /usr/include/c++/6/algorithm:62,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_heap.h:201:55: note:   ‘std::_List_iterator<int>’ is not derived from ‘const std::reverse_iterator<_Iterator>’
       std::__push_heap(__first, _DistanceType((__last - __first) - 1),
                                               ~~~~~~~~^~~~~~~~~~
In file included from /usr/include/c++/6/bits/stl_algobase.h:67:0,
                 from /usr/include/c++/6/algorithm:61,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_iterator.h:387:5: note: candidate: template<class _IteratorL, class _IteratorR> decltype ((__y.base() - __x.base())) std::operator-(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_IteratorR>&)
     operator-(const reverse_iterator<_IteratorL>& __x,
     ^~~~~~~~
/usr/include/c++/6/bits/stl_iterator.h:387:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/6/bits/stl_algo.h:61:0,
                 from /usr/include/c++/6/algorithm:62,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_heap.h:201:55: note:   ‘std::_List_iterator<int>’ is not derived from ‘const std::reverse_iterator<_Iterator>’
       std::__push_heap(__first, _DistanceType((__last - __first) - 1),
                                               ~~~~~~~~^~~~~~~~~~
In file included from /usr/include/c++/6/bits/stl_algobase.h:67:0,
                 from /usr/include/c++/6/algorithm:61,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_iterator.h:1186:5: note: candidate: template<class _IteratorL, class _IteratorR> decltype ((__x.base() - __y.base())) std::operator-(const std::move_iterator<_IteratorL>&, const std::move_iterator<_IteratorR>&)
     operator-(const move_iterator<_IteratorL>& __x,
     ^~~~~~~~
/usr/include/c++/6/bits/stl_iterator.h:1186:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/6/bits/stl_algo.h:61:0,
                 from /usr/include/c++/6/algorithm:62,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_heap.h:201:55: note:   ‘std::_List_iterator<int>’ is not derived from ‘const std::move_iterator<_IteratorL>’
       std::__push_heap(__first, _DistanceType((__last - __first) - 1),
                                               ~~~~~~~~^~~~~~~~~~
In file included from /usr/include/c++/6/bits/stl_algobase.h:67:0,
                 from /usr/include/c++/6/algorithm:61,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_iterator.h:1193:5: note: candidate: template<class _Iterator> decltype ((__x.base() - __y.base())) std::operator-(const std::move_iterator<_IteratorL>&, const std::move_iterator<_IteratorL>&)
     operator-(const move_iterator<_Iterator>& __x,
     ^~~~~~~~
/usr/include/c++/6/bits/stl_iterator.h:1193:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/6/bits/stl_algo.h:61:0,
                 from /usr/include/c++/6/algorithm:62,
                 from prog.cpp:1:
/usr/include/c++/6/bits/stl_heap.h:201:55: note:   ‘std::_List_iterator<int>’ is not derived from ‘const std::move_iterator<_IteratorL>’
       std::__push_heap(__first, _DistanceType((__last - __first) - 1),
                                               ~~~~~~~~^~~~~~~~~~

3 个答案:

答案 0 :(得分:13)

push_heap的参数是随机访问迭代器,而std::list迭代器不是随机访问,只是双向的。

  

类型要求

     
      
  • RandomIt必须符合RandomAccessIterator的要求。
  •   

答案 1 :(得分:7)

来自§25.4.6的ISO C ++ 14标准:

  

堆是两个随机访问迭代器 [a,b)之间范围内的元素的特定组织。

因此该函数需要一个满足RandomAccessIterator概念的迭代器,但std::list<T>::iterator没有。

答案 2 :(得分:3)

因为push_heap()需要random access iterator

不同的C ++容器提供不同类型的迭代器,具有不同的属性和不同的功能。 std::list仅提供双向迭代器,它不满足随机访问迭代器的要求。正如我引用的链接所述,随机访问迭代器实现了除双向迭代器实现的要求之外的其他要求。

因此,需要随机访问迭代器的算法不能使用双向迭代器。