c++ - 通过与不同类型的值进行自定义比较来查找 std::set 的元素

标签 c++ stl set

考虑以下带有自定义比较器的 std::set 玩具示例:

#include <set>

struct A {
  A() : a(cnt++) {}
  const int a;
  static int cnt;
};

int A::cnt = 0;

struct comp {
  bool operator()(const A& left, const A& right)
  {
    return left.a < right.a;
  }
};

int main()
{
  std::set<A, comp> sa;
  for (int i = 0; i < 10; ++i) sa.insert(A());
  return 0;
}

请注意,A 不能简单地从整数创建。

我想在 sa 中寻找给定值为 A::aA无需构造 a A 类型的临时对象,即我正在搜索类似的东西

sa.find(4)

带有自定义比较器,允许直接比较整数与 A 类型的对象。这可能吗?

最佳答案

在 C++14 中,您可以使用“透明”比较器:

#include <iostream>
#include <set>
#include <type_traits>

class A
{
    public: explicit A() : a{cnt++} {}
    private: explicit A(int) = delete;
    public: const int a;
    private: static int cnt;
};

int A::cnt{};

class Comparator
{
    // this member is required to let container be aware that 
    // comparator is capable of dealing with types other than key
    public: using is_transparent = std::true_type;

    public: bool operator()(const int & left, const A& right) const
    {
        return left < right.a;
    }

    public: bool operator()(const A & left, const int& right) const
    {
        return left.a < right;
    }

    public: bool operator()(const A& left, const A& right) const
    {
        return left.a < right.a;
    }
};

int main()
{
    std::set<A, Comparator> sa{};
    for (int i{}; i < 10; ++i)
    {
        sa.emplace();
    }
    std::cout << sa.find(3)->a << std::endl;
    return 0;
}

online compiler

在 C++14 异构查找可用之前 ::boost::intrusive::set :

#include <boost/intrusive/set.hpp>
#include <iostream>

namespace bi = ::boost::intrusive;

// hook contains set node data, supports various options, can be a member
class A: public bi::set_base_hook
<
    bi::link_mode<bi::link_mode_type::safe_link>
>
{
    public: explicit A() : a{cnt++} {}
    private: explicit A(int) = delete;
    public: const int a;
    private: static int cnt;
};

int A::cnt{};

class Comparator
{
    public: bool operator()(const int & left, const A& right) const
    {
        return left < right.a;
    }

    public: bool operator()(const A & left, const int& right) const
    {
        return left.a < right;
    }

    public: bool operator()(const A& left, const A& right) const
    {
        return left.a < right.a;
    }
};

int main()
{
    bi::set<A, bi::compare<Comparator>> sa{Comparator{}};
    for (int i{0}; i < 10; ++i)
    {
        sa.insert(*new A{}); // typically user manages object creation
    }
    // comparators may vary
    std::cout << sa.find(3, Comparator{})->a << std::endl;
    return 0;
}

online compiler

关于c++ - 通过与不同类型的值进行自定义比较来查找 std::set 的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48176182/

相关文章:

c++ - 蓝牙与电脑交互

c++ - TCP 客户端服务器程序

c++ - 自定义分配器有时会因 STL vector 而崩溃

ios - Swift - 从外部设置 UI 元素

python - 在 python 中 - 集合用于测试对象是否在集合中的运算符

c++ - 模板特化基类函数模板缺失

c++ - 删除指针有时会导致堆损坏

c++ - 我如何从 while(getline(cin,tmp)) 跳转?

C++:std::vector [] 运算符

java - 将一个集合分成更小的集合 - Java