c++ - 将 std::set 与基于键的比较器一起使用
问题描述
假设我有一组字符串(或映射),并且我想使用一个自定义比较器,它只比较前 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)
。在这个例子中它很短,但在一般情况下它可能会更长。我想避免这个重复的代码。
一般来说,给定 typesT1, T2
和 function T2 key(T1& const)
,我想要一组T1
根据 进行比较的元素key(a) < key(b)
,其中比较 onT2
已经明确定义。写这个的最好方法是什么?我想过写一个新的class KeyBaseSet
. ,但这对于我的单个用例来说是过度设计的。有没有办法使用std
或 Boost 来做到这一点?
我正在寻找类似于key
在 Python 中排序(https://docs.python.org/3/howto/sorting.html#key-functions)或compare `on`
Haskell 中的成语(https://stackoverflow. com/a/2788262/351105)。
解决方案
您可以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");
std::string
不会为字符串文字构造临时的"abc"
。
推荐阅读
- logout - 请求和经过身份验证的电子邮件不同
- iframe - iOS 独立 webapp iframe cookie
- node.js - 如何摆脱 source-map-support TypeError: frame.getFileName is not a function in node 10
- laravel - 如何使用 Laravel 将类型为 jobber 的用户添加到另一个用户收藏列表
- c++ - C++ 模板函数在 Visual Studio 中不起作用
- html - 在解决方案资源管理器中显示带有黄色感叹号的文件
- regex - 正则表达式,获取服务器地址的结尾
- android - 在不使用父级颜色的情况下使用可绘制的透明背景查看
- c++ - 为什么我的字符串在转换时会给出这样的输出?
- c++ - Windows Media 基础:如何设置编码器属性?