【问题标题】:std::equal_range for vector of pairs throws < operator error对向量的 std::equal_range 抛出 < 运算符错误
【发布时间】:2014-07-08 19:34:24
【问题描述】:

我正在尝试编写一个优先队列/堆实现,它允许迭代、删除元素、在迭代期间更改键和值,以及查找具有特定键的所有元素。 std::priority_queue 不支持迭代,boost::heap 不支持在迭代期间更改键和值。我也尝试过使用std::multimap,但在迭代期间更改值也存在问题。

我的队列存储为std::pairs&lt;double, T&gt;std::vector。我想我可以使用std::sortstd::equal_range 函数而不定义我自己的比较器,因为std::pair automatically overloads the &lt; operator。此外,this question 建议将std::equal_range 与成对容器一起使用是可能的,但我收到std::equal_range 的以下编译器错误。

'bool std::operator <(const std::vector<_Ty,_Ax> &,const std::vector<_Ty,_Ax> &)' : could not deduce template argument for 'const std::vector<_Ty,_Ax> &' from 'const double'

binary '<' : no global operator found which takes type 'std::pair<_Ty1,_Ty2>' (or there is no acceptable conversion)

我的猜测是这与使用模板有关,但在这种情况下,我也预计 std::sort 会失败。

总结

  1. 为什么std::pair &lt; 的自动重载对std::equal_range 不起作用?

  2. 是否需要为我的优先级队列定义比较器?

我的实现如下

测试

int main()
{
    PriorityQueue<double> queue;
    queue.push(1, 1);
    queue.remove(0);
    queue.cleanup(); //This call throws the error when it calls std::equal_range
}

标题

#include <vector>
#include <utility>
#include <algorithm>

template<typename T>
class PriorityQueue
{
    T item;
    typedef typename std::vector<std::pair<double, T>>::iterator It;

    private:
        std::vector<std::pair<double, T>> queue;
        bool isSorted;
        bool hasRemoved;

        void sort(){
            std::sort(queue.begin(), queue.end());
        };

    public:

        PriorityQueue():isSorted(true), hasRemoved(false){};

        void push(double cost, T val)
        {
            isSorted = false;
            queue.push_back(std::make_pair(cost, val));
        };

        void remove(int i)
        {
            hasRemoved = true;
            isSorted = false;
            queue[i].first = DBL_MAX; //Pushes element to end of list
        };

        void cleanup()
        {
            if(!isSorted) sort();
            if(hasRemoved)
            {
                std::pair<It, It> remove = std::equal_range(queue.begin(), queue.end(), DBL_MAX); // This line throws the error
                queue.erase(remove.first, remove.second);
            }
        };
};

【问题讨论】:

  • std::equal_range(queue.begin(), queue.end(), DBL_MAX); 尝试将pair&lt;double, T&gt;double 进行比较。 pair 仅提供与另一个 pair 进行比较的 operator&lt;,按字典顺序比较每个对象的两个成员。
  • 您可以通过从 priority_queue 继承并访问底层容器来迭代它的内容。但是,它很可能是作为堆排序的,而不是排序的。

标签: c++


【解决方案1】:

错误是你给出了一个配对列表,比如{{0,1},{1,2},{2,3}...},并要求找到等于(例如)2 的值范围。编译器不知道如何比较 pair&lt;double,double&gt;double

【讨论】:

  • @dyp 是的,我在重新检查问题后意识到这一点。
  • 是的,这就是我想要的。缺少类型不匹配绝对是一种隧道视觉的情况。鉴于错误的来源,我猜我需要一个自定义比较器来仅匹配第一个成员。
  • 只是一个链接,供未来寻求者了解如何重载比较运算符stackoverflow.com/questions/24308993/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-02
  • 1970-01-01
  • 2021-07-11
  • 2020-06-21
  • 2021-11-07
相关资源
最近更新 更多