【问题标题】:STL priority_queue parametersSTL priority_queue 参数
【发布时间】:2015-04-01 06:49:24
【问题描述】:

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

【问题讨论】:

    标签: c++ stl priority-queue


    【解决方案1】:

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

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

    • 将第三个参数设为函数指针,并将无状态 lambda 传递给构造函数。您还可以传递普通函数指针。例如,

    • 将第三个参数设为std::function&lt;bool(int, int)&gt;,并将与正确签名匹配的任何类型的 lambda 传递给构造函数。您可以传递任何可用于构造std::function&lt;bool(int)&gt;

    例如,

    // 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;});
    

    【讨论】:

    • 嗯,lambdas,像所有的表达式一样,有一个类型。这只是一个难以形容的。
    • @T.C.改写(并添加示例)。
    • 答案很有帮助。但是,它并没有回答我的问题:定义 priority_queue 模板类是否存在根本问题,以便比较函数可以被接受为函数而不是类。我想模板参数必须是函数类型,参数类型=存储在priority_queue中的对象的类型。这可能是不允许的——至少在我尝试编译的示例中它不起作用。无论如何,谢谢。
    • @Ekalavya 显然不是。我的第一个示例接受一个函数。类限制不存在。
    • 它在构造函数中接受一个函数——但不作为模板参数。
    【解决方案2】:

    priority_queue 的第三个模板参数是一个类型。 Lambda 表达式是表达式,而不是类型。表达式具有类型。每个 lambda 表达式都有一个独特的、“无法形容的”类型。几乎唯一可以参考的方法是通过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 的答案中显示的一种方式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-27
      • 1970-01-01
      • 2022-08-03
      • 2011-01-27
      • 2021-09-26
      • 1970-01-01
      • 2011-05-06
      • 1970-01-01
      相关资源
      最近更新 更多