【问题标题】:compilation error with std::priority_queue derived class using std::shared_ptr使用 std::shared_ptr 的 std::priority_queue 派生类的编译错误
【发布时间】:2013-04-25 04:27:30
【问题描述】:

我从 std::priority_queue 派生了一些专门的方法。其中之一 当我添加一个元素并且队列已满时,方法某种固定队列,最小的元素从队列中删除。

template<typename T,
     typename Sequence = std::vector<T>,
     typename Compare = std::less<typename Sequence::value_type> >
class fixed_priority_queue : public std::priority_queue<T, Sequence, Compare> {

    friend class BCQueue_; // to access maxSize_

public:

fixed_priority_queue(unsigned int maxSize) 
: maxSize_(maxSize) {}

void insertWithOverflow(const T& x) {
    if (this->size() == maxSize_) {
        auto beg = this->c.begin();
        auto end = this->c.end();
        auto min = std::min_element(beg, end);
        if(x > *min) {
            *min = x;
            std::make_heap(beg, end);
        }
    }
    else {
       this->push(x);
    }
}

// ...

private:
    fixed_priority_queue() {} 
    const unsigned int maxSize_;
};

这是我使用的比较器:

class ScoreLessThan : public std::binary_function<
    std::shared_ptr<CCandidate>, std::shared_ptr<CCandidate>, bool> {
public:

    bool operator()(
        const std::shared_ptr<CCandidate>& a, const std::shared_ptr<CCandidate>& b) const {
        return a->score > b->score;
    }
};

我包装了我派生的 fixed_priority_queue 类以保持功能有点分离,所以最后我有了这个:

class BCQueue_ : public fixed_priority_queue<
    std::shared_ptr<CCandidate>, std::vector<std::shared_ptr<CCandidate> >,      ScoreLessThan> {
public:
    BCQueue_(size_t maxSize)
    : fixed_priority_queue(maxSize) {}

    bool willInsert(float score) {
        return size() < maxSize_ || top()->score < score;
    }
};

我可以这样使用:

BCQueue_ queue(30);

CCandidate 只是一些数据的持有者。一个属性是score 字段,我在上面的比较器中使用它。

当我使用上面的类和 CCandidate 作为原始指针时,所有编译都会出现问题并且工作正常,现在我想用 std::shared_ptr 替换原始指针(就像我上面所做的那样),我得到一个编译错误:


    ... 199:5: error: no match for ‘operator>’ in ‘x >min.__gnu_cxx::__normal_iterator::operator* [with _Iterator =  std::shared_ptr*, _Container = std::vector >, __gnu_cxx::__normal_iterator::reference = std::shared_ptr&]()’
...
... :199:5: note: candidates are:
... :199:5: note: operator>(int, int) 
... :199:5: note:   no known conversion for argument 2 from ‘std::shared_ptr’ to ‘int’

也许这是一个简单的问题。我不确定我是否正确定义了比较器,或者我是否需要更改insertWithOverflow()x &gt; *min 中的比较,实际上我不知道我应该在那里更改什么。

我应该提到,我在 stackoverflow 上找到了 `insertWithOverflow' 的实现,它正好符合我的需要。见这里:How to make STL's priority_queue fixed-size

就像说的那样,使用原始指针,这一切都没有问题。有人可以帮我解决这个问题。提前致谢!

【问题讨论】:

  • Do not inherit from std::priority_queue,它不是设计为基类。
  • @CaptainObvlious:基本上我知道,但我想做的就是存够,所以选择了这种方式。使用原始指针 CCandidate * 它可以正常工作,没有任何问题。
  • 所以你知道这是错的,被告知这是错的但你还想这样做吗?不错!
  • @CaptainObvlious:我没有添加explicit destructor,只添加了unsigned int作为成员,我认为这样可以节省足够的钱。此派生类是私有类,其他人无法访问。
  • 我认为错误消息与您显示的代码不匹配。如果您声明 insertWithOverflow 采用非常量引用 (T&amp;),这就是您将得到的确切错误。但在您的代码中,它需要一个 const 引用。

标签: c++ shared-ptr priority-queue derived-class


【解决方案1】:

你需要在你的函数中到处使用指定的比较函数:

using std::priority_queue<T, Sequence, Compare>::comp;

void insertWithOverflow(const T& x) {
    if (this->size() == maxSize_) {
        auto beg = this->c.begin();
        auto end = this->c.end();
        auto min = std::min_element(beg, end, comp);
        if(comp(*min, x)) {
            *min = x;
            std::make_heap(beg, end, comp);
        }
    }
    else {
       this->push(x);
    }
}

【讨论】:

  • 这似乎行得通。我补充说。必须为CCandidate 定义一个复制构造函数。它期待CCandidate(const CCandidate * rhs)。所有这一切都让我想到一个问题,如果我使用组合而不是从 std::priority_queue 派生会更好。我通常知道这是要走的路。
猜你喜欢
  • 2020-12-03
  • 2018-02-25
  • 2016-02-24
  • 2022-01-23
  • 2015-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-13
相关资源
最近更新 更多