簡體   English   中英

使用operator!= as作為運算符<在std :: set中是否安全?

[英]Is it safe to use operator != as operator < in a std::set?

我有一個帶有一些成員的結構,我有一個實現的運算符==。 在operator ==的幫助下實現運算符是否安全? 我想在一個集合中使用這個結構,我想檢查這個結構是否是唯一的。

struct Data
{
  std::string str1;
  std::string str2;
  std::string str3;
  std::string str4;

  bool operator==(const Data& rhs)
  {
    if (str1 == rhs.str1
     && str2 == rhs.str2
     && str3 == rhs.str3
     && str4 == rhs.str4
       )
      return true;
    else
      return false;
  }

  // Is this ok??
  bool operator<(const Data& rhs)
  {
    return !this->operator==(rhs);
  }
}

所以當我將這個結構插入到std :: set時會發生什么?

不,這是非常不安全的。 實現它的最簡單方法是通過std::tie

#include <tuple>
struct Data
{
  std::string str1;
  std::string str2;
  std::string str3;
  std::string str4;

  bool operator<(const Data& rhs) const // you forgot a const
  {
      return 
      std::tie(str1, str2, str3, str4) < 
      std::tie(rhs.str1, rhs.str2, rhs.str3, rhs.str4);
  }
}

不,那不安全。 您定義的方式<a < bb < a將同時為真。

所以當我將這個結構插入到std :: set時會發生什么?

行為是未定義的,因此任何事情都是允許的,並且在不同的實現上可能會有所不同。

那么你的代碼建議如果A!=B ,那意味着A<B肯定是錯誤的,因為它也可以是A>B

您將必須以與operator==相同的方式實現><運算operator== ,這意味着通過成員方式比較對象。 由您決定如何確定A是否比基於其成員的B “更多”或“更少”。

如果您在任何標准庫容器中使用該運算符,您將獲得UB。

您需要按照自己的術語定義operator< 雖然您可以執行相反的operator== ,但您無法在operator==方面實現operator<

考慮一下這個真值表中的悖論:

"a" < "b" : TRUE
"b" < "a" : TRUE

如果你的operator<的實現產生了上面的悖論,如果用operator==實現它,那么你就沒有正確實現嚴格的弱排序。 你實施的是亂七八糟的混亂。

您需要確定哪個成員字符串優先於其他成員字符串,然后按順序執行它們之間的比較 - 從最重要到最不重要。

例如,如果字符串的優先級從最重要到最不重要:

  1. str1
  2. str2
  3. str3
  4. str4

...然后這會為operator<

bool operator<(const Data& rhs) const
{
  if( str1 < rhs.str1 )
    return true;
  if( rhs.str1 < str1 )
    return false;
  if( str2 < rhs.str2 )
    return true;
  if( rhs.str2 < str2 )
    return false;
  if( str3 < rhs.str3 )
    return true;
  if( rhs.str3 < str3 )
    return false;
  if( str4 < rhs.str4 )
    return true;
  if( rhs.str4 < str4 )
    return false;

  return false;
}

使用它,您可以選擇接下來根據operator<重新實現operator== 但是,您可以假設時間復雜度固有的低效率:

bool operator==(const Data& rhs) const
{
  return !operator<(rhs) && !rhs.operator<(*this);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM