2017-02-16 120 views
0

我试图push_heaplist<int>,但编译失败抱怨列表迭代器。如果我将列表更改为向量,它可以正常工作。不能push_heap列表<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

由于push_heap()需要random access iterator

不同的C++容器提供了不同类型的迭代器,具有不同的属性和不同的功能。 std::list只提供了一个双向迭代器,它不符合随机访问迭代器的要求。正如我在引用的链接中指出的那样,随机访问迭代器除了实现双向迭代器以外,还实现了其他需求。

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

7

从ISO C++ 14标准在§25.4.6:

A heap is a particular organization of elements in a range between two random access iterators[a,b) .

所以函数需要满足RandomAccessIterator的概念,但std::list<T>::iterator不迭代器。

相关问题