通过与不同类型的值进行自定义比较来查找 std::set 的元素
考虑以下带有自定义比较器的 std::set
玩具示例:
Consider the following toy example of an std::set
with a custom comparator:
#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
不能简单地从整数创建.
Note that A
cannot simply be created from an integer.
我想在 sa
中寻找具有 A::a
给定值的 A
,A
类型的临时对象,即我正在寻找类似的东西
I would like to look for an A
with a given value of A::a
in sa
, without constructing a temporary object of type A
, i.e. I am searching for something like
sa.find(4)
带有一个自定义比较器,允许直接将整数与 A
类型的对象进行比较.这可能吗?
with a custom comparator that allows for direct comparison of integers with objects of type A
. Is that possible?
推荐答案
使用 C++14 你可以使用透明"比较器:
With C++14 you can utilize "transparent" comparator:
#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;
}
在线编译器
在 ::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;
}
在线编译器
相关文章