【问题标题】:overload operator< in using std::set在使用 std::set 时重载运算符<
【发布时间】:2013-11-23 04:49:58
【问题描述】:

这是我第一次使用 std::set 容器,操作符 std::less 有问题。

我声明集合:

std::set<MyClass*, std::less<MyClass> > _set;

然后,我为 MyClass 重载 operator ;问题似乎与类和指针之间的混合有关,因为我有这个错误消息:

no match for call to '(std::less<MyClass>) (MyClass *const&, MyClass *const&)'

【问题讨论】:

  • 任何使用原始指针容器的设计都被破坏了。您的问题只是另一个证明,因为它甚至让您感到困惑。
  • 只是std::set&lt;MyClass&gt; myClassSet;
  • @Griwes 那是错误的。将原始指针作为映射类型的std::mapstd::map 更常见的用法之一。
  • 你不能使用std::less&lt;MyClass&gt;,因为它不是用来比较MyCLass*s的函数。相反,您应该编写自己的比较函数...struct Cmp { bool operator()(const MyClass* p_lhs, const MyClass* p_rhs) const { return *p_lhs &lt; *p_rhs; } }; 并将其指定为set 的第二个模板参数。
  • @Griwes Off hand(并且没有看到他的代码的任何其他内容),我确实怀疑这里的正确答案是使用值。由于像 Java 这样的语言,大量 C++ 初学者在不应该使用动态分配的情况下确实使用了动态分配。在这种情况下,正确的答案使用值,而不是用智能指针模拟Java的垃圾收集。一旦你消除了这些情况,智能指针的情况就几乎消失了。几乎所有带有指针的关联容器都用于导航。

标签: c++ set std operator-keyword


【解决方案1】:

您只想使用std::set&lt;MyClass&gt;。比较器默认为std::less

【讨论】:

  • 这很大程度上取决于set 的用途。如果使用指针的原因是对象存在于其他地方,那么他必须使用原始指针。 (我认为我没有遇到过将智能指针放在set 中的情况。)
  • (en.cppreference.com/w/cpp/memory/shared_ptr/operator_cmp) "请注意,shared_ptr 的比较运算符只是比较指针值;不比较指向的实际对象。"
  • @JamesKanze,我刚刚给了你一个案例,可以将智能指针放在一个集合中——在类型上启用多态性。
  • @Griwes 但非实体类型多态的频率如何?鉴于他似乎相对较新,建议价值语义是一个好主意。但是,如果值语义不适用,建议给相对较新的人使用智能指针是个坏主意。真正适用的情况很少。
  • @JamesKanze,恰恰相反;向相对较新的人引入 raw 指针是个坏主意。在原始指针之前和容器之后引入智能指针(因为这个问题是关于std::set,我想说我们已经达到了这一点)是教授语言的理智方式。
【解决方案2】:

您为MyClass 重载了operator&lt;,但您的集合有指针 指向MyClass

简单的答案是不使用指针。如果您觉得必须使用指针,那么答案是为您的集合编写一个自定义比较器。

struct Comp
{
    bool operator()(MyClass* x, MyClass* y);
};

std::set<MyClass*, Comp> _set;

【讨论】:

  • 或专门化 std::less 并缩短 set 声明。
猜你喜欢
  • 1970-01-01
  • 2014-08-07
  • 2019-08-21
  • 1970-01-01
  • 2021-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多