【问题标题】:Find in a set containing self defined type在包含自定义类型的集合中查找
【发布时间】:2015-09-18 13:51:52
【问题描述】:

我有一个存储自定义数据的集合,我想通过键值搜索它。

这是一个简单的例子:

struct Data {
  Data(int x, int y):x(x), y(y){}
  int x;
  int y;
};

struct Compare {
  bool operator() (const Data& lhs, const Data& rhs) {
    return lhs.x < rhs.x;
  }
};

int main()
{
  set<Data, Compare> s;
  s.insert(Data(2, 77));
  s.insert(Data(3, 15));
  s.insert(Data(1, 36));
  for (auto i:s)
    cout<<i.x<<" "<<i.y<<endl;

  auto i = s.find(3);  // <-- Not working
  auto i = s.find(Node(3, 0));
  if (i != s.end())
    cout<<"found"<<endl;
  else
    cout<<"not found"<<endl;
}

此集合仅按x 排序,但我必须创建一个临时对象以在集合中搜索:s.find(Node(3, 0))

是否可以仅按键搜索?即s.find(3)?

【问题讨论】:

  • 你可能想看看std::map
  • @n.m.不错,会考虑的

标签: c++ set


【解决方案1】:

在c++14中,可以使用is_transparent

查找具有与值 x 相当的键的元素。 此重载仅参与重载决议,如果 qualified-id Compare::is_transparent 是有效的并且表示一个类型。它 允许在不构造Key实例的情况下调用该函数

struct Compare {
  using is_transparent = std::true_type;
  bool operator() (const Data& lhs, const Data& rhs) const {
    return lhs.x < rhs.x;
  }
  bool operator() (const Data& lhs, const int & rhsx) const {
    return lhs.x < rhsx;
  }
  bool operator() (const int & lhsx, const Data& rhs) const {
    return lhsx < rhs.x;
  }
};

现在你的代码是valid

【讨论】:

    【解决方案2】:

    你为什么不写这样的东西?

    Data myFind(const set<Data, Compare>& s, int x) {
       auto it = s.find(Node(x, 0));
       return *it;
    }
    

    【讨论】:

      【解决方案3】:

      您的代码有错误。 std::set 是一个 unique 容器,这意味着它不希望包含两个彼此相等的值。但是,通过为集合提供一个仅使用x 的比较函数,您已经做到了,因此具有相同 x 分量的两个值将被集合视为相等,而不管它们的 y 是否匹配。这将防止您为 x 插入多个值。 (这可能是你想要的......如果是这样,请忽略这部分。)更好的比较会通过查看 y 来打破 x 中的联系(这被称为“词典”比较:

      struct Compare {
        bool operator() (const Data& lhs, const Data& rhs) {
          if(lhs.x != rhs.x) return lhs.x < rhs.x;
          return lhs.y < rhs.y;
        }
      };
      

      现在,至于通过与键类型不同的东西进行搜索。由于关联容器的搜索功能中有一些新的重载,这在 C++14 中成为可能。有关更多信息,请参阅Raw pointer lookup for sets of unique_ptrs 的第一个答案。基本上,你给你的比较器一个“is_transparent”成员来标记它,你让它能够将Datas 与你打算搜索的任何类型进行比较。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-04-05
        • 2018-07-17
        • 1970-01-01
        • 1970-01-01
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多