STL priority_queue参数

时间:2015-04-01 06:49:25

标签: c++ stl priority-queue

创建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的设计者选择不允许它?

2 个答案:

答案 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;类型。几乎唯一可以引用它的方法是通过autodecltype

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;答案。