【问题标题】:Bool operator overloading not working布尔运算符重载不起作用
【发布时间】:2013-11-16 19:19:35
【问题描述】:

代码示例:

#include <queue>
#include <vector>

using namespace std;

class Cell
{
public:
    int totalCost = 0;
};

class Helper
{
public:
    struct Comparator
    {
        bool operator()(Cell const *lfs, Cell const *rhs)
        {
            return lfs->totalCost < rhs->totalCost;
        }
    };
};

priority_queue<Cell*, vector<Cell*>, Helper::Comparator> path;

void function(Cell* cell)
    {
        cell->totalCost += rand() % 1000;
        path.push(cell);
    }

    int main()
    {
        Helper help;

        Cell first;
        Cell second;
        Cell third;
        Cell fourth;
        Cell fifth;

        Cell* firstPtr = &first;
        Cell* secondPtr = &second;
        Cell* thirdPtr = &third;
        Cell* fourthPtr = &fourth;
        Cell* fifthPtr = &fifth;



        function(firstPtr);
        function(secondPtr);
        function(thirdPtr);
        function(fourthPtr);
        function(fifthPtr);

        return 0;
    }

调试器截图:

我正在创建一个优先级队列,我尝试重载 () 运算符,但由于某种原因它根本不起作用(如调试器中所示)。

我感觉指针有问题,但我不知道到底是什么。

【问题讨论】:

  • 你告诉它使用函子,但你从不实例化函子。
  • @ZacHowland ... 这意味着它在优先级队列的默认 ctor 中默认构造。
  • 为什么你认为它不起作用?对我来说看起来像是一个有效的堆。
  • @mah 但它使用了。队列的第三个模板参数是 Helper::Comparator,因此它由队列的默认 ctor 默认构造。
  • @mah 使用,在path的声明中,这就是所有需要的。

标签: c++ debugging pointers operator-overloading priority-queue


【解决方案1】:

我在您的代码中没有发现问题。除了你忘记初始化随机数生成器。

#include <iostream>
#include <queue>
#include <vector>
#include <cstdlib>

using namespace std;

class Cell
{
public:
    int totalCost = 0;
};

class Helper
{
public:
    struct Comparator
    {
        bool operator()(Cell const *lfs, Cell const *rhs)
        {
            return lfs->totalCost < rhs->totalCost;
        }
    };
};

priority_queue<Cell*, vector<Cell*>, Helper::Comparator> path;

void function(Cell* cell)
{
    cell->totalCost += rand() % 1000;
    path.push(cell);
}

int main()
{
    srand(time(0));
    Helper help;

    Cell first;
    Cell second;
    Cell third;
    Cell fourth;
    Cell fifth;

    Cell* firstPtr = &first;
    Cell* secondPtr = &second;
    Cell* thirdPtr = &third;
    Cell* fourthPtr = &fourth;
    Cell* fifthPtr = &fifth;

    function(firstPtr);
    function(secondPtr);
    function(thirdPtr);
    function(fourthPtr);
    function(fifthPtr);

for(;path.size();path.pop()) std::cout << path.top()->totalCost <<"\n";

    return 0;
}

它输出:

luk32@debianvm:~/projects/tests$ ./a.out 
896
725
370
200
130
luk32@debianvm:~/projects/tests$ ./a.out 
699
672
285
250
208
luk32@debianvm:~/projects/tests$ ./a.out 
772
582
388
223
153
luk32@debianvm:~/projects/tests$ ./a.out 
869
807
670
642
182

这是预期的。也许您会感到困惑,因为它不会对项目进行排序。但它不必。只有第一个(顶部)必须比所有其他(根据比较器)都要大。其余元素不遵循n &gt; n+1。这是因为优先队列是在堆上实现的。它可以通过这种方式更快地运行。因为插入元素需要O(log n) 时间。保持所有元素排序需要O(n) 插入操作。

【讨论】:

  • 这让我感到困惑,我认为它应该对所有元素进行排序,但我想这不是真的。感谢您清理它。
【解决方案2】:

std::priority_queue 是在堆上实现的,由于它没有使用“最小堆”,因此会产生一些违反直觉的副作用,因此项目从最高到最低的顺序排列强>.

简而言之,您的比较运算符有错误的方式 - 如果您希望优先级队列按降序排列,则需要测试 rhs &lt; lhs 而不是相反。

#include <queue>
#include <vector>
#include <iostream>

struct Cell
{
    int m_totalCost;
    Cell(int totalCost=0) : m_totalCost(totalCost) {}

    struct PriorityCompare
    {
        bool operator()(Cell const* lhs, const Cell* rhs) const
        {
            return rhs->m_totalCost < lhs->m_totalCost;
        }
    };
};

std::priority_queue<Cell*, std::vector<Cell*>, Cell::PriorityCompare> g_path;

int main()
{
    Cell first(rand() % 1000);
    Cell second(rand() % 1000);
    Cell third(rand() % 1000);
    Cell fourth(rand() % 1000);
    Cell fifth(rand() % 1000);

    g_path.push(&first);
    g_path.push(&second);
    g_path.push(&third);
    g_path.push(&fourth);
    g_path.push(&fifth);

    while (g_path.empty() == false) {
        Cell* cell = g_path.top();
        g_path.pop();
        std::cout << cell->m_totalCost << "\n";
    }
    return 0;
}

现场演示:http://ideone.com/BEjt4R 输出

383
777
793
886
915

---- 附录----

请记住,底层的std::vector 用于实现heap,因此通过调试器查看时,这些项目不会按顺序出现在向量中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    相关资源
    最近更新 更多