创建STL priority_queue时,第三个参数(决定如何比较队列中的元素以决定哪个最大的参数)必须是定义函数运算符的类。如果可以提供lambda表达式会更方便。为什么不允许这样做?如果lambda表达式没有捕获任何变量,那么它应该被认为是编译时常量,对吗?
struct compare{
bool operator()(int p, int q){return p > q;}
};
priority_queue< int, vector<int>, compare> intpq;
priority_queue< int, vector<int>,
[](int p, int q){return p > q;}
> intpq2;
第二个定义,即intpq2,给出错误:模板参数3无效。接受第二个定义是否存在根本问题,或者仅仅是priority_queue的设计者选择不允许它?
答案 0 :(得分:2)
std::priority_queue
的第三个参数是一个类型。 lambda表达式不是类型,而是表达式(您可以将其视为某事物的实例或对象)。最重要的是,lambdas没有一个可以知道先验的类型,但是无状态lambdas确实转换为指向函数的指针。
您可以使用一些解决方法来使用lambdas实例化priority_queues:
使第3个参数成为函数的指针,并将无状态lambda传递给构造函数。您还可以传递普通函数指针。例如,
将第3个参数设为std::function<bool(int, int)>
,并将与正确签名匹配的任何类型的lambda传递给构造函数。您可以传递任何可用于构建std::function<bool(int)>
。
例如,
// no capture. Pointer to function is OK
std::priority_queue<int, std::vector<int>, bool (*)(int, int)>
q2([](int a, int b){return a < b;});
或
// capture. Can't use pointer to function.
std::priority_queue<int, std::vector<int>, std::function<bool(int, int)>>
q2([some_var](int a, int b){return a < b;});
答案 1 :(得分:1)
priority_queue
的第三个模板参数是一种类型。 Lambda表达式是表达式,而不是类型。表达式具有类型。每个lambda表达式都有一个不同的&#34; unspeakable&#34;类型。几乎唯一可以引用它的方法是通过auto
和decltype
:
auto cmp = [](int a, int b){return a < b;};
std::priority_queue<int, std::vector<int>, decltype(cmp)> q1(cmp);
如果您只是在本地使用q1
,那也没关系。如果你需要传递它,你的函数用户可能很难拼写priority_queue
的类型,你可能需要采用@ juanchopanza&#中显示的方法之一39;答案。