我的程序结构类似于:
class A {
private:
std::set<B> members;
public:
void func(const C& arg) {
std::set<B>::iterator iter = members.find(a);
if(iter != members.end()) {
iter->check(arg);
}
}
}
class B {
private:
std::deque<C> writers;
public:
void check(const C& arg) {
if(std::find(writers.begin(), writers.end, arg) != writers.end()) {
/* Code */
}
}
}
class C {
private:
int id;
public:
bool operator==(const C& arg) {
return arg.id == this->id;
}
}
编译时,我收到以下错误消息:
no matching function for call to ‘B::check(const C&) const’
note: candidates are: void B::check(const C&) <near match>
如果我将check()
声明为const
,则编译器会抛出一个错误,要求将C类中的重载运算符==
声明为const
。我不知道将重载运算符设为const
是否正确。 (我尝试了一次,据我所知,它也有一些错误)。
我一直试图解决这个问题超过五天,仍然没有任何线索。
答案 0 :(得分:3)
首先,operator==
应为const
。除非您想要混淆用户,否则它不会修改数据,也不会修改数据。通常,每个不需要修改对象状态的函数都应该是const
,以便提供最大的灵活性(即允许通过常量引用进行调用)。
同样可以应用于B::check
,如果它只测试而不是修改,那么它应该是const
。并且在A::func
中进行扩展,如果它不需要修改那么它应该是const。
错误消息在不同的编译器中会略有不同。在您的情况下,编译器执行了重载解析,并且找不到与其抱怨的调用匹配:
没有用于调用'B :: check(const C&amp;)const'的匹配函数 注意:候选人是:void B :: check(const C&amp;)
这表示它看到了您的成员但丢弃了它,因为它需要具有const
标记的成员函数。在其他编译器中,错误消息将包含以下行:调用void B::check(const C&)
丢弃限定符这有点复杂并试图说在const上调用非const成员函数引用将需要忽略const
限定符。
答案 1 :(得分:3)
您肯定会将B::check()
和C::operator==
声明为const
,因为它们不会更改对象状态中的任何内容。
它也可能不那么明显,但std::set<B>::iterator
实际上是const_iterator
(假设你使用的是C ++ 11编译器)!因此,您无法通过B
迭代器从set
对象调用任何非const函数成员。
答案 2 :(得分:-1)