STL priority_queue 参数

STL priority_queue parameters

创建 STL priority_queue 时,第三个参数(决定如何比较队列中的元素以确定哪个最大的参数)必须是 class,其中函数运算符是定义。如果可以提供 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的设计者选择不允许?

std::priority_queue的第三个参数是类型。 lambda 表达式不是类型,而是表达式(您可以将其视为某个实例或对象)。最重要的是,lambda 没有可以已知的类型 先验,但无状态 lambda 确实会转换为指向函数的指针。

您可以使用一些解决方法来使用 lambda 实例化 priority_queues:

  • 将第三个参数设为指向函数的指针,并将无状态的 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;});

priority_queue的第三个模板参数是一个类型。好吧,Lambda 表达式是 表达式 ,而不是类型。一个表达式有一个类型。每个 lambda 表达式都有一个不同的 "unspeakable" 类型。几乎唯一可以引用它的方法是通过 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 的答案中显示的方法之一。