简体   繁体   English

C++ std::priority_queue 使用 lambda 表达式

[英]C++ std::priority_queue uses the lambda expression

There is statement that the compiler can't pass.有语句编译器不能通过。 I can't understand it.我无法理解。 Can anyone tell me in detail or How to fix it ?谁能详细告诉我或者如何解决? Best wishes to you.向你致以最良好的祝愿。

The statement as follow:声明如下:

    std::priority_queue<int,std::vector<int>,[](const int& lhs,const int& rhs)
    { 
        return lhs<rhs;
    } > pq;

The compiler given the information as follow:编译器给出的信息如下:

 type/value mismatch at argument 3 in template parameter list for 
'template<class _Tp, class _Sequence, class _Compare> class std::priority_queue'

The std::priority_queue inducted in cppreference site: http://en.cppreference.com/w/cpp/container/priority_queue cppreference 站点中引入的 std::priority_queue: http : //en.cppreference.com/w/cpp/container/priority_queue

mainly structure as follow:主要结构如下:

template<
    class T,
    class Container = std::vector<T>,
    class Compare = std::less<typename Container::value_type>
> class priority_queue;

The declaration you show has a value , namely a lambda, as actual template argument where the formal template argument (parameter) is a type.您显示的声明有一个,即 lambda,作为实际模板参数,其中正式模板参数(参数)是一种类型。


Here is an example of using a type as template argument:这是使用类型作为模板参数的示例:

#include <vector>
#include <queue>

auto main()
    -> int
{
    struct My_less
    {
        auto operator()( int const a, int const b ) const
            -> bool
        { return a < b; }
    };

    std::priority_queue< int, std::vector<int>, My_less > pq;
}

Example of using a lambda expression as comparator:使用 lambda 表达式作为比较器的示例:

#include <vector>
#include <queue>

auto main()
    -> int
{
    std::priority_queue< int, std::vector<int>, auto(*)(int,int)->bool > pq{
        []( int a, int b )->bool { return a < b; }
        };
}

C++11 §5.1.12/19 says “The closure type associated with a lambda-expression has a deleted (8.4.3) default constructor and a deleted copy assignment operator.”. C++11 §5.1.12/19 说“与 lambda 表达式关联的闭包类型有一个已删除的 (8.4.3) 默认构造函数和一个已删除的复制赋值运算符。”。 That means that the type of a lambda expression can not be used to instantiate the lambda from scratch.这意味着 lambda 表达式的类型不能用于从头开始实例化 lambda。 And the lambda does not convert implicitly to std::less<T> that's expected, which means you cannot use it directly as constructor argument either (and anyway std::less is stateless).并且 lambda 不会隐式转换为预期的std::less<T> ,这意味着您也不能将其直接用作构造函数参数(无论如何std::less是无状态的)。 But you can specify a comparator type that the lambda does convert to, and then use the lambda as constructor argument.但是您可以指定 lambda 转换为的比较器类型,然后使用 lambda 作为构造函数参数。 In the above code that comparator type is a simple raw function pointer.在上面的代码中,比较器类型是一个简单的原始函数指针。


In practice, it is useful to define the lambda functions elsewhere and pass them to the target function as function pointers在实践中,在别处定义 lambda 函数并将它们作为函数指针传递给目标函数很有用

#include <vector>
#include <functional>
#include <queue>

void foo(std::function<bool(int &a, int &b)> comparison)
{
    std::priority_queue< int, std::vector<int>, decltype(comparison)> pq {
        comparison
    };
}
auto main()
    -> int
{
    auto comparison = [](int,int)->bool {
        return a < b; 
    }

    foo(Comparison);
}

As mentioned, the issue is that the third parameter of the template requires a type , not a value .如前所述,问题在于模板的第三个参数需要type ,而不是value

However, from C++20 non-capturing lambdas are default-constructable.但是,从 C++20 开始,非捕获 lambda 是默认可构造的。 Since every lambda has a unique type, this means that the following will work:由于每个 lambda 都有一个独特的类型,这意味着以下内容将起作用:

std::priority_queue<int, std::vector<int>, decltype([](int lhs, int rhs) {
  return lhs < rhs;
})> pq;
// use pq like normal

If you need to use this particular comparison frequently, you can typedef it:如果你需要经常使用这个特殊的比较,你可以 typedef 它:

using my_pqueue = std::priority_queue<int, std::vector<int>, decltype([](int lhs, int rhs) {
  return lhs < rhs;
})>;

// ...

my_pqueue a;  // don't need to pass in the lambda to the constructor
my_pqueue b;

Live example: https://godbolt.org/z/cG3P4Y现场示例: https : //godbolt.org/z/cG3P4Y

    auto comp=[](const int& lhs,const int& rhs)
        { 
            return lhs<rhs;
        };
    std::priority_queue<int,std::vector<int>,decltype(comp) > pq(comp);

or或者

    std::priority_queue<int,std::vector<int>,function<bool(const int&,const int&) > pq([](const int& lhs,const int& rhs){ 
            return lhs<rhs;
        });

为了达到最佳使用效果,您可以这样做:

priority_queue<State*,vector<State*>,function<bool(const State*,const State*)>> pq([](const State* s1, const State* s2){return s1->hValue>s2->hValue;}); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM