繁体   English   中英

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

[英]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对于任何ab都是true ,除非a == b 特别是a < btrue ,并且b < a也被认为是true 这不符合严格弱排序的要求,并导致未定义的行为。 您可以使用“正常” <来比较字符串。

暂无
暂无

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

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