我们可以使用异构查找比较器对 STL 关联容器执行"partial-match"搜索吗?
Can we use heterogeneous lookup comparator to perform a "partial-match" search on STL associative containers?
所以我在STL的关联容器中寻找对异构查找的支持(从C++14开始),但对我们能做什么和不应该做什么有点困惑
以下片段
#include <algorithm>
#include <iostream>
#include <set>
struct partial_compare : std::less<>
{
//"full" key_type comparison done by std::less
using less<>::operator();
//"sequence-partitioning" comparison: only check pair's first member
bool operator ()(std::pair<int, int> const &lhs, int rhs) const
{
return lhs.first < rhs;
}
bool operator ()(int lhs, std::pair<int, int> const &rhs) const
{
return lhs < rhs.first;
}
};
int main()
{
//Using std::set's lookup
{
std::cout << "std::set's equal_range:n";
std::set <std::pair<int, int>, partial_compare> s{{1,0},{1,1},{1,2},{1,3},{2,0}};
auto r = s.equal_range (1);
for (auto it = r.first; it != r.second; ++it)
{
std::cout << it->first << ", " << it->second << 'n';
}
std::cout << "std::set's lower_bound + iteration on equivalent keys:n";
auto lb = s.lower_bound(1);
while (lb != std::end(s) && !s.key_comp()(lb->first, 1) && !s.key_comp()(1, lb->first))
{
std::cout << lb->first << ", " << lb->second << 'n';
++lb;
}
}
//Using algorithms on std::set
{
std::cout << "std::equal_rangen";
std::set <std::pair<int, int>> s{{1,0},{1,1},{1,2},{1,3},{2,0}};
auto r = std::equal_range (std::begin(s), std::end(s), 1, partial_compare{});
for (auto it = r.first; it != r.second; ++it)
{
std::cout << it->first << ", " << it->second << 'n';
}
}
return 0;
}
使用clang-5/libc++编译时生成以下输出:
std::set's equal_range:
1, 1
std::set's lower_bound + iteration on equivalent keys:
1, 0
1, 1
1, 2
1, 3
std::equal_range
1, 0
1, 1
1, 2
1, 3
当使用gcc-7.1.0编译时,会出现以下内容:
std::set's equal_range:
1, 0
1, 1
1, 2
1, 3
std::set's lower_bound + iteration on equivalent keys:
1, 0
1, 1
1, 2
1, 3
std::equal_range
1, 0
1, 1
1, 2
1, 3
通过阅读最初的N3465提案,我认为我在这里所做的应该很好,并且在概念上与提案的初始示例中的内容相同:在查找过程中的"部分匹配",依赖于"序列划分的概念">
现在,如果我理解正确的话,标准中实际包含的是N3657,但这似乎并没有改变概念,因为它"只是"专注于确保异构查找成员模板只有在提供的比较器"is_transparent"时才可用
所以,我真的不明白为什么在clang/libc++中使用std::set的equal_range
成员模板不会产生与gcc或等效的"lower_bound
+扫描"相同的结果。我是不是遗漏了什么,以这种方式使用异构查找实际上违反了标准(然后clang是对的,equal_range
和lower_bound
+扫描之间的差异可能是由于UB造成的),还是clang/libc++错了?
编辑:在阅读了现在被接受的答案后,我找到了libc++的相关错误报告
SO上还有一个关于libc++和libstdc++之间equal_range
模板成员行为差异的特定问题,我在搜索时没有找到
不确定是应该删除还是关闭,因为我链接的那个没有可接受的答案。
这是libc++中的一个错误:它的equal_range实现(位于r315179)在找到"equal"元素时立即返回两个迭代器,即使进行异构比较也是如此。
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- C++,系统无法执行指定的程序
- 使用C++中的模板和运算符重载执行矩阵运算
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 执行函数时导致崩溃的变量
- 无论条件是否为true,if总是在c++中执行
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 在C++中对T*类型执行std::move的意外行为
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如何在没有信号的情况下从C++执行QML插槽
- 如何确认我的constexpr表达式实际上已经在编译时执行
- C++17中的并行执行策略
- QML按钮点击功能执行顺序
- 程序在执行程序的其余部分之前退出
- 为什么catch中的代码没有被执行
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 将执行、作业和WinAPI相乘
- 对字符数组中的元素执行逐位操作
- 为什么不执行"partial RVO"?
- 我们可以使用异构查找比较器对 STL 关联容器执行"partial-match"搜索吗?