2011-04-27 162 views
29

我有以下錯誤的代碼,我想在VC2010中編譯,但我得到錯誤C2974這隻發生在我包含lambda表達式,所以我猜它有東西與此相關。C++ priority_queue與lambda比較錯誤

typedef pair<pair<int, int>, int> adjlist_edge; 
priority_queue< adjlist_edge , vector<adjlist_edge>, 
    [](adjlist_edge a, adjlist_edge b) -> bool { 
     if(a.second > b.second){ return true; } else { return false; } 
    }> adjlist_pq; 

我已經知道了模板的形式定義是正確的,因爲

priority_queue<int , vector<int>, greater<int>> pq; 

按預期工作。任何想法我做錯了什麼? lambda看起來有什麼不對,我可能會忽略它嗎?謝謝閱讀!

+0

的http://stackoverflow.com/questions/3867276/can-the-type-of-a-lambda-expression-be-expressed – 2011-04-28 09:12:17

回答

46

首先定義拉姆達對象,然後將它傳遞給該模板的類型使用decltype,並將其直接傳遞給構造函數。

auto comp = [](adjist a, adjlist b) { return a.second > b.second; }; 
priority_queue< adjlist_edge , vector<adjlist_edge>, decltype(comp) > 
    adjlist_pq(comp); 
+0

謝謝,如果我必須單獨聲明它,那麼你認爲使用函數的lambda對象有什麼好處? – ameer 2011-04-27 18:01:52

+0

Re:默認構造函數:[expr.prim.lambda]/19表示默認的構造函數和複製賦值操作符被刪除,隱式定義了複製構造函數和析構函數。 – 2011-04-27 18:14:24

+0

@mmutz:謝謝,編輯! – Potatoswatter 2011-04-27 20:07:27

13

priority_queue將比較器作爲模板參數。 Lambda函數是對象,因此不能用作模板參數(只有極少數類型可以是其中的整型)。

您可以嘗試使用decltype有:

priority_queue< adjlist_edge , vector<adjlist_edge>, 
       decltype([](adjlist_edge a, adjlist_edge b) -> bool { 
       if(a.second > b.second){ return true; } else { return false; } 
       })> 
adjlist_pq([](adjlist_edge a, adjlist_edge b) -> bool { 
       if(a.second > b.second){ return true; } else { return false; } 
      }); 

做不到這一點(,它會),你可以使用function<>

priority_queue< adjlist_edge , vector<adjlist_edge>, 
       function<bool(adjlist_edge,adjlist_edge)> > 
adjlist_pq([](adjlist_edge a, adjlist_edge b) -> bool { 
       if(a.second > b.second){ return true; } else { return false; } 
      }); 
+0

+1可能重複了比interjay接近,但仍不起作用,因爲每個lambda函數都有唯一的類型,甚至兩個具有相同定義的對象。 – Potatoswatter 2011-04-27 17:32:05

+0

函數更好,因爲它不重複代碼(顯然,它是唯一正確的事情)。 – 2011-04-27 17:32:26

+0

@亞歷山大:還有另一種選擇,犧牲是一種單線,但比「功能」更清潔。 – Potatoswatter 2011-04-27 17:39:43