用任意比较器设置C++

use*_*868 4 c++

我有以下C++代码

#include <set>
#include <string>
#include <iostream>
using namespace std;

class Pair {
  public:
    string lhs;
    string rhs;
    Pair();
    Pair( string l, string r ) {
      lhs=l;
      rhs=r;
    };
};

struct compare {
  bool operator()(const Pair& a, const Pair& b) const{
    if ( ( a.lhs == b.lhs && a.rhs == b.rhs ) || ( a.lhs == b.rhs && a.rhs == b.lhs ) ) {
      cout << "MATCH" << endl;
    }
    return ( a.lhs == b.lhs && a.rhs == b.rhs ) || ( a.lhs == b.rhs && a.rhs == b.lhs );
  }
};

int main () {
  set<Pair, compare > s;
  Pair p( string("Hello"), string("World") );
  s.insert(p);
  cout << s.size() << "\n";
  Pair q( string("World"), string("Hello") );
  s.insert(q);
  cout << s.size() << "\n";
  compare cmp;
  cout << cmp( p, q );

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

调用编译的代码给出:

1
MATCH
MATCH
2
MATCH
Run Code Online (Sandbox Code Playgroud)

某种方式的设定s的结束成对p和q尽管使得比较它们标识为相同的事实.为什么?

任何帮助都感激不尽!

更新:

非常感谢您的出色答案以及您的善意和专业帮助.正如您可能已经猜到的那样,我是C++的新手.

无论如何,我想知道,如果Antoine的答案可以用lambda表达式完成吗?

就像是:

std::set< …, [](){ my_comparator_code_here } > s;
Run Code Online (Sandbox Code Playgroud)

????

Mar*_*k B 6

a std::set(它是一个有序容器)的比较运算符需要识别严格的弱排序而不是任何你想要的任意测试.通常,正确实施operator<该工作.

如果您的比较运算符未提供严格的弱序列(因为您没有),则行为将是未定义的.没有办法解决C++标准的这个要求.

请注意,在需要进行相等比较的某些情况下,必须使用operator<两次进行比较.

您是否考虑过使用std::pair<std::string, std::string>而不是自己滚动?

我现在已经重读了你的问题五次了,我开始想知道你想要的是一个set字符串所在的对,first并且second就比较而言并不重要.在这种情况下,@ Antoine似乎是适合您的解决方案.