C++ 为什么可以';t this std::find compare这些对象
通常,当我执行std::find时,我会将谓词作为第三个参数,但这次我想我会做得不同,我不明白为什么它不起作用C++ 为什么可以';t this std::find compare这些对象,c++,c++11,std,C++,C++11,Std,通常,当我执行std::find时,我会将谓词作为第三个参数,但这次我想我会做得不同,我不明白为什么它不起作用 #include <iostream> #include <vector> #include <algorithm> struct RenderJob { RenderJob() {}; int renderJob_ID; bool operator==(RenderJob& rhs) { return rhs.re
#include <iostream>
#include <vector>
#include <algorithm>
struct RenderJob
{
RenderJob() {};
int renderJob_ID;
bool operator==(RenderJob& rhs) { return rhs.renderJob_ID == this->renderJob_ID; }
};
int main()
{
RenderJob foo;
RenderJob foo2;
foo == foo2; // Works
std::vector<RenderJob> renderJobs;
std::find(renderJobs.begin(), renderJobs.end(), foo); // Doesn't work
}
如果情况正好相反:
foo2 == *pToRenderJob; // This would fail because the
// operator==(RenderJob&) the actual argument
// is not const. Very subtle rules
您关闭了
const
限定符
bool operator==(const RenderJob& rhs) const { ... }
在我看来,这是一个常量正确性问题。请尝试以下方法:
bool operator==(RenderJob const &rhs) const {
return rhs.renderJob_ID == this->renderJob_ID;
}
你自己做比较是有效的,因为你只是传递了一些简单的对象,这些对象不是临时对象,也不是常量。使用std::find
,比较函数将(至少通常)接收对集合中对象的引用(通常是常量限定的),因此它需要能够接收常量限定的引用
但这仍然没有意义,在上面的示例中,右侧是foo2
,它不是常量,应该指向非常量运算符==
。除非有一条一般规则规定,const
和非const
不能进行比较
语言中没有规则规定不能比较const
和非const
对象。您必须确保可以使用适当的const
限定符对它们进行比较
线路
*pToRenderJob == foo2;
相当于
pToRenderJob->operator==(foo2);
foo2.operator==(*pToRenderJob)
这不起作用,因为不能使用pToRenderJob
调用非const
成员函数<代码>foo2
不是这里的问题
如果你使用
foo2 == *pToRenderJob
相当于
pToRenderJob->operator==(foo2);
foo2.operator==(*pToRenderJob)
这也是一个问题,因为函数的参数是const
对象,而函数需要非const
引用。同样地,foo2
不是问题所在
将函数设为
const
成员函数并将参数设为const
引用可确保操作符两侧的const
和非const
对象的所有组合都可以毫无问题地使用。哦,我明白了,它起作用了。但是,我自己能够比较它们。std::find中的compare函数不是只使用操作符==函数吗?@Zebrafishfind
通过常量引用获取要比较的值。是的,谢谢。特别是const RenderJob,而不是函数后面的一个。但是我不明白,我可以自己比较它们,因为操作符==重载,std::find不是只使用操作符==函数吗?两者都应该是常量。当编译器正在查找const数据上的运算符时,它将拒绝考虑不保证const行为的运算符。现在我理解了,但是,在我的另一个例子中,右边是非const的,因此我认为应该调用非const运算符==,当然,除非在比较常量和非常量时通常存在问题。非常量对象可以升级为常量对象。记住,const只是意味着一个对象被标记为“不允许修改它”,不管对象的实际可修改性如何。在您的示例中,您不能执行*const==foo2
或*pToRenderJob==foo2
,因为运算符==
未声明允许常量
左操作数变为*this
。如果该类有一个函数void f(),则情况也是如此代码>-您无法执行constit->f()
或pToRenderJob->f()
。但是如果您将该函数更改为void f()const代码>,这两个都可以。谢谢,许多规则正在慢慢设置。您还应该在类中定义renderJob\u ID
:int renderJob\u ID{}
。保留未初始化的对象是过早的优化。在您的示例中,foo.renderJob_ID和foo.renderJob_ID具有不确定值,如果您声明std::vector renderJobs(10)
以创建一个10的向量renderJobs
,那么这10个对象的renderJob_ID都将具有不确定值。因此,即使在将const添加到operator==参数之后,您的代码也将继续不起作用。这非常有趣,因此在我创建实际函数const时起作用的*pToRenderJob==foo2中。“非常有趣,也很微妙的规则。”斑马鱼。习惯这些规则需要一段时间,但更重要的是,随着对语言理解的加深,这些规则开始变得有意义。