WeaklyTyped
WeaklyTyped

Reputation: 1341

Using const_iterator in non constant function

I have a program structured similiar to:

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;
      }
}

When I compile this, I get the following error message:

no matching function for call to ‘B::check(const C&) const’  
note: candidates are: void B::check(const C&) <near match>

If I declare check() as const then the compiler throws an error demanding that the overloaded operator == in Class C to be declared as const. I don't know if making the overloaded operator as const is the right thing to do. (I tried it once and as far as I can recollect it also gave some error).

I been trying to solve this for more than five days and still no leads.

Upvotes: 0

Views: 224

Answers (3)

The first thing is that operator== should be const. It does not modify data, nor should it ever unless you want to confuse your users. In general every function that need not modify the state of the object should be const as to provide the maximal flexibility (i.e. allow calls through constant references).

The same can be applied to B::check, if it does only test and not modify, then it should be const. And by extension in A::func, if it does not need to modify then it should be const.

The error message will be slightly different in different compilers. In your case the compiler performed overload resolution and did not find a match to the call which is what it complains about:

no matching function for call to ‘B::check(const C&) const’
note: candidates are: void B::check(const C&)

Which indicates that it saw your member but discarded it as it needed a member function with the const tag. In other compilers the error message will contain something on the lines of: calling void B::check(const C&) discards qualifiers which is a bit more convoluted and tries to say that calling a non-const member function on a const reference would require ignoring the const qualifier.

Upvotes: 3

CyberGuy
CyberGuy

Reputation: 2813

Remember that when it is possible you should prefer non-const version. At least this is what scott mayber said.

Here is a long discussion:

Should I prefer iterators over const_iterators?

Upvotes: -1

Rost
Rost

Reputation: 9089

You definitely shall declare B::check() and C::operator== as const as they don't change anything in object state.

Also it may be not so obvious, but std::set<B>::iterator is actually const_iterator (suppose you are using C++11 compiler)! So you are unable to call any non-const function members from B objects via set iterator.

Upvotes: 3

Related Questions