忽略比较运算符顺序的对

时间:2015-08-03 19:51:24

标签: c++

是否有人知道如何通过std :: map对两个具有相同内容但顺序不同的对进行处理?以下是:

typedef std::pair<std::string, std::string> Pair;
Pair pair1("first", "last");
Pair pair2("last", "first");

if (!(pair1 < pair2) && !(pair2 < pair1))
   std::cout << "I need this to happen please" << std::endl;
else
   std::cout << "boo" << std::endl;

我对小于运算符(运算符&lt;)特别感兴趣。我已经尝试了很多东西,但每次我认为我得到它,我发现一个比较不起作用的情况,导致std :: map有重复记录或丢失记录。

我目前的解决方法是使用std :: set,它可以满足我的需求,但在我的情况下我还需要保持与创建对时相同的顺序。由于std :: set对所有内容进行排序,我无法使用它。

简单地说,解决算子&lt;在下面:

struct MyPair
{
  std::string _First;
  std::string _Second;

  bool opreator<(const myPair &aRHS) const;
}

这是我尝试过的(以及它的许多变体):

(_First < aRHS._First || (_First == aRHS._First && _Second < aRHS._Second )) ||
(_First < aRHS._Second || (_First == aRHS._Second && _Second < aRHS._First ))

我现在放弃了(这解释了我在这里的原因)。

2 个答案:

答案 0 :(得分:0)

使用的一种策略:

  1. 对每个MyPair的第一个和第二个进行排序。
  2. 比较排序后的第一个和第二个对象。

    bool MyPair::opreator<(const myPair &aRHS) const
    {
       lhsFirst = (this->_First < this_->_Second) ? this->_First : this->_Second;
       lhsSecond = (this->_First < this_->_Second) ? this->_Second : this->_First;
    
       rhsFirst = (aRHS._First < this_->_Second) ? aRHS._First : aRHS._Second;
       rhsSecond = (aRHS._First < this_->_Second) ? aRHS._Second : aRHS._First;
    
       if ( lhsFirst != rhsFirst )
       {
          return (lhsFirst < rhsFirst);
       }
       else
       {
          return (lhsSecond < rhsSecond);
       }
    }
    

答案 1 :(得分:0)

以下示例首先确保对first的{​​{1}}和second进行排序,然后对两对进行比较:

rhs

<强>输出

#include <map>
#include <iostream>
#include <tuple>

template <typename T1, typename T2>
struct OrderIndependentPair
{
  T1 first;
  T2 second;

  bool operator<(const OrderIndependentPair &rhs) const
  {
    if (rhs.first < rhs.second)
    {
        return std::tie(first, second) < std::tie(rhs.first, rhs.second);
    }
    else
    {
        return std::tie(first, second) < std::tie(rhs.second, rhs.first);
    }
  }
};

int main()
{
    using Pair = OrderIndependentPair<std::string, std::string>;

    using Map = std::map<Pair,int>;

    Map m;
    Pair p1{"foo", "bar"};
    m[p1] = 42;

    Pair p2{"bar", "foo"};
    std::cout << m[p1] << std::endl;
    std::cout << m[p2] << std::endl;
    return 0;
}

<强> live on coliru

您还可以使用42 42 和自定义比较器:

std::pair

<强> live on coliru