【问题标题】:C++ std::priority_queue uses the lambda expressionC++ std::priority_queue 使用 lambda 表达式
【发布时间】:2016-12-09 04:40:44
【问题描述】:

有编译器不能通过的语句。我无法理解。谁能详细告诉我或如何解决?向您致以最良好的祝愿。

声明如下:

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

编译器给出的信息如下:

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

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

主要结构如下:

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

【问题讨论】:

    标签: c++ c++11 lambda


    【解决方案1】:

    您展示的声明有一个 ,即 lambda,作为实际模板参数,其中形式模板参数(参数)是一个类型。


    下面是一个使用类型作为模板参数的例子:

    #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;
    }
    

    使用 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 说“与 lambda 表达式关联的闭包类型有一个已删除 (8.4.3) 的默认构造函数和一个已删除的 复制赋值运算符。”。这意味着不能使用 lambda 表达式的类型从头开始实例化 lambda。并且 lambda 不会隐式转换为预期的std::less&lt;T&gt;,这意味着您也不能直接将其用作构造函数参数(无论如何std::less 是无状态的)。但是您可以指定 lambda 确实转换为的比较器类型,然后使用 lambda 作为构造函数参数。在上面的代码中,比较器类型是一个简单的原始函数指针。


    在实践中,在别处定义 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);
    }
    

    【讨论】:

    • 哦,我知道了,谢谢。 lambda 表达式是实例而非类型。然后我们应该如何将 lambda 表达式应用于需要类型的地方。在这种情况下,我尝试使用 std::function 多次使用 lambda。你能给个主意吗?
    • 我不确定lambda表达式是否没有隐式转换为预期的std::less&lt;T&gt;,因为std::less&lt;T&gt;有构造函数或复制赋值运算符,导致lambda表达式无法转换它,因此,如果我们想使用 lambda 表达式来应用,我们必须在类型不是预期的实例时指定比较器类型?是这样吗?
    【解决方案2】:

    如前所述,问题在于模板的第三个参数需要 type,而不是 value

    但是,从 C++20 开始,非捕获 lambda 是默认可构造的。由于每个 lambda 都有一个唯一的类型,这意味着以下内容将起作用:

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

    如果你需要经常使用这个特定的比较,你可以 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;
    

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

    【讨论】:

      【解决方案3】:
          auto comp=[](const int& lhs,const int& rhs)
              { 
                  return lhs<rhs;
              };
          std::priority_queue<int,std::vector<int>,decltype(comp) > pq(comp);
      

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 不是最好的主意。与创建自己的仿函数类或将 decltype 应用于 lambda 相比,这会产生开销。
        • 感谢您提及这一点。我实际上是编程新手。所以学习
        猜你喜欢
        • 2011-04-22
        • 1970-01-01
        • 2013-04-28
        • 1970-01-01
        • 2023-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-19
        相关资源
        最近更新 更多