在包含自定义类型

时间:2015-09-18 13:51:53

标签: c++ set

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

这是一个简单的例子:

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)

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

您的代码有错误。 std::set唯一容器,这意味着它不希望包含两个彼此相等的值。但是,通过为集合提供仅使用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”成员来标记它,你可以将Data与你想要搜索的任何类型进行比较。

答案 2 :(得分:0)

在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