【问题标题】:priority_queue with custom comparator as value in map constructor error将自定义比较器作为映射构造函数中的值的 priority_queue 错误
【发布时间】:2020-09-24 15:01:46
【问题描述】:

我创建了一个带有自定义比较器的priority_queue,它以字典顺序存储字符串,它按预期工作。[参考。 this]]

现在,我希望它在unordered_map 中具有价值,我得到了error: no matching constructor for initialization ...,我找到的最接近的是this。我意识到我也需要将比较器传递给构造函数,但是如何?

这是我现在的代码:

#include <iostream>
#include <vector>
#include <unordered_map>
#include <queue>
using namespace std; // Used to make code less verbose


int main() {
  auto cmp = [](string s1, string s2){
        return s1.compare(s2) > 0;
      };

  using myQuque = priority_queue<string, vector<string>, decltype(cmp)> ;
  // This code works
  myQuque pq(cmp);
  pq.push("ZZ");
  pq.push("AA");
  pq.push("CC");
  while(!pq.empty()){
    cout << pq.top() << " ";
    pq.pop();
  }

  // This doesn't. How do I pass 'cmp' to constructor?
  unordered_map<string, myQuque> table;
  auto p = table["r"];
  p.push("ZZ");
  p.push("AA");

}

https://godbolt.org/z/cvPfPd

然后我意识到我也可以在这个应用程序中使用 multiset,但我仍然想知道如何在 map 中使用带有自定义比较器的 priority_queue

【问题讨论】:

    标签: c++ stl


    【解决方案1】:

    使用 lambda 是个坏主意...只需通过比较模板参数提供比较,然后不需要构造函数参数...

    #include <iostream>
    #include <vector>
    #include <unordered_map>
    #include <queue>
    using namespace std; // Used to make code less verbose
    
    struct Cmp {
        bool operator()(const string& s1, const string& s2) const {
            return s1.compare(s2) > 0;
        }
    };
    
    int main() {
      using myQuque = priority_queue<string, vector<string>, Cmp>;
      // This code works
      myQuque pq;
      pq.push("ZZ");
      pq.push("AA");
      pq.push("CC");
      while(!pq.empty()){
        cout << pq.top() << " ";
        pq.pop();
      }
    
      // This doesn't. How do I pass 'cmp' to constructor?
      unordered_map<string, myQuque> table;
      auto p = table["r"];
      p.push("ZZ");
      p.push("AA");
    }
    

    请注意,我已将比较更改为通过 const 引用获取参数,避免深度复制每次比较所比较的文本(至少只要比您的 std::string 实现可能具有的任何短字符串优化缓冲区长)。

    【讨论】:

      【解决方案2】:

      地图在创建新元素时使用默认构造函数。您可以使用指针,但您需要分配每个新条目:

       unordered_map<string, shared_ptr<myQuque>> table;
       auto p = make_shared<myQueue>(cmp);
       table["r"] = p;
       p->push("ZZ");
       p->push("AA");
      

      【讨论】:

        【解决方案3】:

        问题是使用自定义运行时比较器,myQuque 的默认构造函数不可用。

        std::unordered_map::operator[] 必须能够为值使用默认构造,以防没有为特定键准备好的值。这是必需的,因为它返回对可在赋值表达式中使用的值的引用。

        要修复它你必须删除operator[],你可以使用这个:

          unordered_map<string, myQuque> table;
          auto &p = table.emplace("r", cmp).first->second;
          p.push("ZZ");
          p.push("AA");
        

        演示:https://godbolt.org/z/bPnrEe

        作为替代方案,您可以向priority_queue 提供静态比较器作为 Tony Delroys 的回答。在这种情况下,myQuque 将具有默认构造函数并且问题消失。

        【讨论】:

          猜你喜欢
          • 2021-10-10
          • 1970-01-01
          • 2019-11-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-29
          • 1970-01-01
          相关资源
          最近更新 更多