簡體   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