在shared_ptr上修改std::less

Modify std::less on a shared_ptr

本文关键字:std less 修改 shared ptr      更新时间:2023-10-16

这就是我所拥有的:

struct Foo {
  int index;
}
std::set<std::shared_ptr<Foo>> bar;

我想按bar的元素的索引排序,而不是按与指针相关的默认std::less<std::shared_ptr<T>>函数排序。

我知道我可以键入std::set<std::shared_ptr<Foo>, std::owner_less<std::shared_ptr<Foo>>> bar,但我更喜欢使用以前的语法

我尝试定义std::less<std::shared_ptr<Foo>>,但实际上set函数并没有使用它。我有办法做到这一点吗?

如果你想通过它们的索引进行比较,你必须编写一个比较器来检查它们的索引。std::less<>会做错误的事情(因为它不知道index),std::owner_less<>会做错误事情(因为他仍然不会比较Foo,而是与它们的所有权语义有关)。

你必须写:

struct SharedFooComparator {
    bool operator()(const std::shared_ptr<Foo>& lhs,
                    const std::shared_ptr<Foo>& rhs) const
    {
        return lhs->index < rhs->index;
    }
};

并使用它:

std::set<std::shared_ptr<Foo>, SharedFooComparator> bar;

您还可以将其推广为shared_ptr的通用比较器:

struct SharedComparator {
    template <typename T>
    bool operator()(const std::shared_ptr<T>& lhs,
                    const std::shared_ptr<T>& rhs) const
    {
        return (*lhs) < (*rhs);
    }
};

然后简单地使CCD_ 10具有可比性。

您可以在std命名空间中提供自己的less<shared_ptr<Foo>>专业化。

namespace std
{
   template<>
   class less<shared_ptr<Foo>>
   {
   public:      
      bool operator()(const shared_ptr<Event>& a, const shared_ptr<Event>& b)
      {
         // Compare *a and *b in some way
      }
   };
}

然后您可以在没有比较器的情况下形成set<shared_ptr<Foo>>。我需要这个priority_queue<shared_ptr<Foo>>,而我不想使用priority_queue<Foo*, vector<Foo*>, int (*)(const Foo*, const Foo*)>。我并不为此感到骄傲,但它确实有效。