所以我在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_range\n";
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;
}
Run Code Online (Sandbox Code Playgroud)
使用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
Run Code Online (Sandbox Code Playgroud)
使用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
Run Code Online (Sandbox Code Playgroud)
通过阅读最初的N3465提议,我认为我在这里所做的应该很好,并且在概念上与提案的初始示例中的相同:在查找期间的"部分匹配",依赖于"序列分区的概念".
现在,如果我理解正确,标准中最终的结果是N3657,但这似乎没有改变概念,因为它"只是"专注于确保异构查找成员模板仅在提供的比较器时可用" is_transparent".
所以,我真的不明白为什么equal_range在clang/libc ++中使用std :: set的成员模板不能产生相同的gcc结果或等效的" lower_bound+ scan".我错过了什么,并且以这种方式使用异构查找实际上违反了标准(然后clang是正确的,equal_range而且lower_bound+ 和scan 之间的区别可能是由于UB),还是clang/libc ++错了?
编辑:阅读现在接受的答案后,我能够找到libc ++ 的相关错误报告.
还有有关的行为的差异一个具体问题equal_range的libc ++和libstdc ++模板之间的成员在这里上,这样,在做我的搜索我没有找到.
不确定是否应该删除或关闭它,因为我链接的那个没有接受的答案.