[英]custom comparator without default constructor as template parameter
讓我們看一個從兩個排序數組中找到最小m
對數字的玩具示例。 拋開算法效率問題不談,我想為優先級隊列提供一個在初始化期間需要某些參數的比較器:
class Foo {
struct natural_order {
const std::vector<int> &x,&y;
natural_order( const std::vector<int> &x, const std::vector<int> &y ): x(x), y(y) {};
bool operator () ( const std::pair<int,int> &a, const pair<int,int> &b ) const {
return x[a.first]+y[a.second] < x[b.first]+y[b.second];
}
};
struct cmp {
std::unique_ptr<natural_order> o;
cmp( const std::vector<int> &x, const std::vector<int> &y ) {
o= std::make_unique<natural_order>(x,y);
}
bool operator () ( const std::pair<int,int> &a, const pair<int,int> &b ) const {
return (*o)(b,a);
}
};
public:
std::vector<std::vector<int>> m_smalles_pairs( std::vector<int> &x, std::vector<int> &y, int m ) {
std::vector<std::vector<int>> res(m);
std::priority_queue<int,std::vector<int>,cmp(x,y)> pq; //<-- the problem is here. Does not compile
for ( int i= 0; i < m; ++i ) {
auto pr= pq.top(); pq.pop();
res[i]= std::vector<int>{x[pr.first],y[pr.second]};
if ( pr.first+1 < x.size() )
pq.push({pr.first+1,pr.second});
if ( pr.second+1 < y.size() )
pq.push({pr.first,pr.second+1});
}
return res;
}
};
本質上,我希望用參數初始化比較器,但是如何將其作為priority_queue
的第三個參數提供? 如果不需要x
和y
參數,我會簡單地在上面寫cmp
。
編輯:它似乎使用 lambdas 在類似的行中進行,如這里描述的C++ priority_queue with lambda compare error我能夠解決我的問題,但只是好奇struct
-comparator 是否允許這種事情。
本質上,您的代碼的問題在於Compare的實現。 從技術上講,Compare-class 必須滿足一些要求:
類型 T 滿足BinaryPredicate ---> CopyConstructible
您的類cmp
不可復制構造,因為其成員之一是std::unique_ptr
(無法復制)。
所以我想說,一個合適的解決方案應該是根據這個原則重構你的設計。 我不知道你的問題的全部領域,所以我不能建議什么是正確的設計(而且這可能是個人選擇)。
也許,您可以從類中刪除std::unique_ptr
並將natural_order
類型作為成員。 當然,這意味着不同的復制構造調用。
此時,您可以使用適當的構造函數初始化std::priority_queue
的比較器。
(2) explicit priority_queue(const Compare& compare)
: priority_queue(compare, Container()) { }
你的代碼應該是這樣的:
std::priority_queue<int,std::vector<int>,cmp> pq(cmp{x, y});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.