为 unordered_set 重载 () 运算符

overloading () operator for unordered_set

我有一个 class,我将其对象放入 unordered_set。 为此,我编写了自定义哈希生成器和比较器,以便能够使用 unordered_set 中的 class 对象。一切正常。这个 class 的比较器看起来像这样:

struct MyClassComparator
{
  bool
  operator()(const MyClass & obj1, const MyClass & obj2) const
  {
    if (obj1.getName() == obj2.getName())
      return true;
    return false;
  }
};

所以我正在比较对象的名称(字符串)(没什么特别的)。我使用它来使用 .find 函数在集合中查找 MyClass 对象。

现在的问题是: 是否可以重载此 () 运算符导致以下代码

struct MyClassComparator
{
  bool
  operator()(const MyClass & obj1, const MyClass & obj2) const
  {
    if (obj1.getName() == obj2.getName())
      return true;
    return false;
  }

  bool
  operator()(const MyClass & obj1, const std::string & name) const
  {
    if (obj1.getName() == name)
      return true;
    return false;
  }
};

并像

一样使用 .find 函数
my_set.find("my_class_name")

如果是,这样做是否会产生性能开销。

std::unordered_set::find 需要一个 const Key& key 参数,所以如果你想能够使用 my_set.find("my_class_name") 那么 MyClass 必须可以从 const char[].

这将创建一个临时密钥用作 find 的参数。在这个阶段我根本不会担心性能。这将是一个过早的优化。

我建议使用 std::string 而不是普通的 C 字符串:

struct MyClass
{
     MyClass(const std::string& s);
};

然后:

using namespace std::string_literals;
my_set.find("my_class_name"s);

另外,作为旁注

 if (obj1.getName() == obj2.getName())
      return true;
 return false;

可以用更简单的方式重写(推荐):

return obj1.getName() == obj2.getName();

如果您想使用 std::unorderd_set::value_type 以外的数据类型进行搜索,您需要一个地图,而不是一个集合。

class MyClassMap {
   public:
     myclass_map::iterator insert( MyClass& object ) {
        return _map.insert( object.get_Name() );
     }

     myclass_map::iterator find( MyClass& object  ) {
       myclass_map::iterator it = _map.find( object.getName() );
       if( it != _map.end() && it->getName() == object.getName() )
          return it;
       return _map.end();
     }

     myclass_map::iterator find( const std::string& name ) {
       return _map.find(name);
     }


   private:
     typedef std::unordered_map<
         const std::string&,
         MyClass*,
         MyClassHash,
         MyClassComparator
       > myclass_map;

     myclass_map _map;
};