簡體   English   中英

沒有默認構造函數作為模板參數的自定義比較器

[英]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的第三個參數提供? 如果不需要xy參數,我會簡單地在上面寫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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM