简体   繁体   English

插入 std::set 时重复<std::tuple<std::string, …> &gt; </std::tuple<std::string,>

[英]Duplicates when inserting into std::set<std::tuple<std::string, …>>

I tried to use std::tuple as an element of std::set where std tuple consists of std::string and a bool (for this example only, in normal use case the tuple consists of 3 elements).我尝试将 std::tuple 用作 std::set 的一个元素,其中 std 元组由 std::string 和一个 bool 组成(仅对于此示例,在正常用例中,元组由 3 个元素组成)。 The string of the tuple shall be unique, therefore I created comparator that would sort the elements on the first element of the tuple.元组的字符串应该是唯一的,因此我创建了比较器,它将对元组的第一个元素上的元素进行排序。 However, when inserting into aforementioned set I do get duplicate elements in the container.但是,当插入上述集合时,我确实在容器中得到了重复的元素。 I cannot see where I am making a mistake.我看不出我在哪里犯了错误。 Thanks in advance for suggestions!提前感谢您的建议!

#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;
}

Debugger snippet调试器片段

Output:
ahoy
duplicates
creates
this
ahoy

std::string::compare returns int (neg, 0, positive) not bool (less than), std::string::compare返回int (neg, 0, positive) not bool (小于),

you want你要

std::get<0>(l).compare(std::get<0>(r)) < 0;

or或者

std::get<0>(l) < std::get<0>(r);

a.compare(b) returns: 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)

However, the comparators return value is converted to a bool and anything but 0 is converted to true , hence your comparator considers a < b to be true for any a and b unless a == b .但是,比较器返回值转换为bool并且除0之外的任何值都转换为true ,因此您的比较器认为a < b对于任何ab都是true ,除非a == b In particular a < b is true and b < a is considered as true as well.特别是a < btrue ,并且b < a也被认为是true This is not in accordance with the requirement of a strict weak ordering and causes undefined behavior.这不符合严格弱排序的要求,并导致未定义的行为。 You can use the "normal" < to compare the strings.您可以使用“正常” <来比较字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM