2011-04-27 159 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