[英]Duplicates when inserting into std::set<std::tuple<std::string, …>>
我尝试将 std::tuple 用作 std::set 的一个元素,其中 std 元组由 std::string 和一个 bool 组成(仅对于此示例,在正常用例中,元组由 3 个元素组成)。 元组的字符串应该是唯一的,因此我创建了比较器,它将对元组的第一个元素上的元素进行排序。 但是,当插入上述集合时,我确实在容器中得到了重复的元素。 我看不出我在哪里犯了错误。 提前感谢您的建议!
#include <set>
#include <functional>
#include <iostream>
using namespace std;
int main() {
using tuple_t = std::tuple<std::string, bool>;
std::function<bool(const tuple_t &, const tuple_t &)> tupleCmp =
[](const tuple_t & l, const tuple_t & r) -> bool {
return static_cast<bool>(std::get<0>(l).compare(std::get<0>(r)));
};
set<tuple_t, decltype(tupleCmp)> s(tupleCmp);
s.insert(make_tuple("ahoy", false));
s.insert(make_tuple("this", false));
s.insert(make_tuple("creates", false));
s.insert(make_tuple("duplicates", false));
s.insert(make_tuple("ahoy", false));
for (const auto & i : s){
cout << get<0>(i) << endl;
}
auto debug_stop = 0;
}
Output:
ahoy
duplicates
creates
this
ahoy
std::string::compare
返回int
(neg, 0, positive) not bool
(小于),
你要
std::get<0>(l).compare(std::get<0>(r)) < 0;
或者
std::get<0>(l) < std::get<0>(r);
a.compare(b)
返回:
0 when the strings are equal
negative when a comes before b (ie a < b)
positive when b comes before a (ie b < a)
但是,比较器返回值转换为bool
并且除0
之外的任何值都转换为true
,因此您的比较器认为a < b
对于任何a
和b
都是true
,除非a == b
。 特别是a < b
为true
,并且b < a
也被认为是true
。 这不符合严格弱排序的要求,并导致未定义的行为。 您可以使用“正常” <
来比较字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.