将 std::set 与基于键的比较器一起使用
Using std::set with a key-based comparator
>假设我有一组(或映射(字符串,我想使用仅比较前 5 个字符的自定义比较器。所以"abcde"和"abcdef"在我的集合中是一样的。
typedef std::set<std::string, Cmp> MySet;
编写 CMP 的最佳方法是什么?
显而易见的方式是这样的:
struct Cmp
{
bool operator()(const string& x, const string& y)
{
return (x.substr(0, 5) < y.substr(0, 5));
}
}
问题是此代码重复.substr(0, 5)
.在此示例中,它很短,但在一般情况下,它可能会更长。我想避免这种重复的代码。
一般来说,给定T1, T2
类型和函数T2 key(T1& const)
,我想要一组根据key(a) < key(b)
进行比较的T1
元素,其中对T2
的比较已经明确定义。写这个最好的方法是什么?我想过写一个新的class KeyBaseSet
,但那会为我的单一用例过度设计。有没有办法使用std
或 Boost 来做到这一点?
我正在寻找类似于在 Python (https://docs.python.org/3/howto/sorting.html#key-functions( 中排序时的key
参数或 Haskell (https://stackoverflow.com/a/2788262/351105( 中的compare `on`
习语。
您可以使用密钥策略自定义Cmp
。最小示例:
template<class Key>
struct Compare_on {
Compare_on(Key key = Key()) : key_(key)
{}
template<class T>
bool operator()(const T& x, const T& y) const {
return key_(x) < key_(y);
}
private:
Key key_;
};
struct First3 {
std::string_view operator()(const std::string& s) const {
return std::string_view(s).substr(0, 3);
}
};
// Example:
std::set<std::string, Compare_on<First3>> set;
set.insert("abc1");
set.insert("abc2");
演示
<小时 />Compare_on
可以通过使其成为透明比较器来改善:
template<class Key>
struct Compare_on {
using is_transparent = void;
Compare_on(Key key = Key()) : key_(key)
{}
template<class T1, class T2>
bool operator()(const T1& x, const T2& y) const {
return key_(x) < key_(y);
}
private:
Key key_;
};
struct First3 {
template<class T>
std::string_view operator()(const T& s) const {
return std::string_view(s).substr(0, 3);
}
};
现在当我们这样做时
auto pos = set.find("abc");
不会为字符串文本"abc"
构造临时std::string
。
演示 2
你的问题可以用高阶函数来解决。本质上是一个函数,它采用T2 key(const T1&)
函数并返回一个可用作std::set
比较器的新函数。像这样:
auto make_comp(T key) {
return [key](const auto& v1, const auto& v2){return key(v1) < key(v2);};
}
显然,此示例需要通用 lambda,但也应该可以使用模板结构来实现这一点:)
应该可以将集合定义为std::set<decltype(make_comp([](){...}))>
。
- std::设置自定义比较器
- C++中"std::sort"比较器的不同类型
- 将 std::set 与基于键的比较器一起使用
- 带自定义比较器的最小优先级队列
- 函数类作为比较器
- 优先级队列自定义比较器
- 什么是自定义比较器以及如何在 C++ 的排序函数中使用它?
- 没有默认构造函数作为模板参数的自定义比较器
- set_intersection使用自定义设置比较器
- 如何为集合 c++ 建立比较器
- C++复杂情况的比较器通过参数问题
- 对于BTreeMap和其他依赖于Ord的东西,是否有等效于C++比较器对象?
- 对没有比较器或λ函数的向量进行排序?
- "operator()"在重载运算符方法中是什么意思,在priority_queue(STL)中用作C++中的比较器?
- 用户定义的结构是否有默认C++比较器?
- C++设置了一个用于排序的比较器和另一个用于唯一性的比较器
- gtest 期望无序元素与自定义比较器/匹配器一起使用
- 如何在 C++11 中将 std::max 与自定义比较器一起使用?
- 为什么set_symmetric_difference无法与比较器一起使用
- 如何使用自定义比较器函数将所有字谜组合在一起