假设我有一个像这样的简单类:
class Test {
public:
Test(int reference) { m_reference = reference; }
void feed(int x) { m_data.push_back(x); }
int get() { return m_data.front(); }
private:
int m_reference;
std::vector<int> m_data;
};
我想将值输入std::vector
而不是std::priority_queue
。我不想返回.front()
的值,而是希望基于自定义比较函数来{{1}的.get()
的{{1}}值。假设将此自定义比较计算为值和实例.top()
之间的绝对差。
我不知道如何在类属性中声明priority_queue
。
我尝试过:
reference
然后:
std::priority_queue
我也这样尝试过bool compare(int a, int b) {
return std::abs(a - m_reference) < std::abs(b - m_reference);
}
,但这会引发多个错误:
std::priority_queue<int, std::vector<int>, decltype(&Test::compare)> m_priority;
但是这行不通(请参阅Repl.it)。
请问如何解决这个问题?
答案 0 :(得分:4)
我设法通过使用使其工作:
std::function<bool(int,int)> comp = [this](int a, int b) { return std::abs(a - m_reference) < std::abs(b - m_reference); };
与
Test(int reference) : m_priority(comp) { m_reference = reference; }
和
std::priority_queue<int, std::vector<int>, decltype(comp)> m_priority;
您还需要#include <functional>
如果我正确理解了您的问题,这就是您想要的?
如果您不希望出现任何性能缺陷,也可以将比较器设置为struct
或类似的值,并使用它代替std::function
。
更新:
带有struct的版本看起来像这样(您可以传递this
指针而不是引用int
,但也可以使用它):
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
class Test {
public:
Test(int reference) : m_priority(comp(m_reference)) { m_reference = reference; }
void feed(int x) { m_data.push_back(x); }
int get() { return m_priority.top(); }
struct comp {
int& reference;
comp(int& ref) : reference(ref) {}
bool operator()(int a, int b) { return std::abs(a - reference) < std::abs(b - reference); };
};
private:
int m_reference;
std::vector<int> m_data;
std::priority_queue<int, std::vector<int>, comp> m_priority;
};
答案 1 :(得分:3)
如果您使用std::function
很好(可能会有一点开销),它可以工作,但是您尝试将lambda提交到类型声明中:
std::priority_queue<
int,
std::vector<int>,
std::function<bool(int,int)> comp = [this](int a, int b) { return std::abs(a - m_reference) < std::abs(b - m_reference); }> m_priority;
这不起作用。您需要使用std::function
作为类型:
std::priority_queue<
int,
std::vector<int>,
std::function<bool(int,int)>> m_priority;
,然后将lambda作为参数提交到m_priority
ctor中:
Test(int reference) :
m_reference( reference ),
m_priority( [ref=reference]( int a, int b ) {
return std::abs( a - ref ) < std::abs( b - ref );
} )
{
}
然后它会工作。 Live example
答案 2 :(得分:1)
如果您要更改m_reference
的值,则需要重新排序std::priority_queue
。下面是一种(可能)笨拙的方法,如果经常执行和/或队列很大,则成本很高,但是可以完成工作。该代码应作为@Slavas答案的附件。
public:
void set_reference(int x) {
m_reference = x;
sort();
}
private:
void sort() {
std::priority_queue<int, std::vector<int>, std::function<bool(int,int)>> tmp(
[this](int a, int b) { return std::abs(a - m_reference) < std::abs(b - m_reference); }
);
while(m_priority.size()) {
tmp.emplace(std::move(m_priority.top()));
m_priority.pop();
}
std::swap(tmp, m_priority);
}