0
class A { void koo(){} void foo() const {this->koo();} }; int main() { A a; a.foo(); } 

I tried to call a non-const function inside const function.

error: passing ‘const A’ as ‘this’ argument of ‘void A::koo()’ discards qualifiers [-fpermissive] 
  1. What is the meaning of this error?
  2. Can I use mutable keyword for this, If that, how? (as this post)
  3. Can I use const_cast for this. If that, how? (as this post)
  4. Are there ant other way to do this?
12
  • it means you are trying to call a non-const function from within a const. Nope. Yes - but hacky (const_cast<A*>(this)->koo()). Yes, make koo() const and any state it operates on mutable. Commented Oct 8, 2012 at 10:06
  • What are you actually trying to do inside of koo()? Commented Oct 8, 2012 at 10:08
  • 1
    This is exactly the reason for the const qualifier, it prevents you executing non-const code on a const object. You may need to rethink your design, if you're having this problem, or maybe the function that your calling the non-const member function from really should be const. Commented Oct 8, 2012 at 10:08
  • @Nim const_cast will lead to undefined behaviour if koo really mutates the object. Commented Oct 8, 2012 at 10:09
  • @R.MartinhoFernandes It won't, because it's called on a non-const object. And if called on a const object, it's undefined regardless of whether it mutates the object, is it not? Commented Oct 8, 2012 at 10:10

4 Answers 4

4
  1. In function foo, this has type const A*. In order to call a non-const function on it, you'd end up with this in koo having the same value but type A*, i.e. it would discard const qualifiers.

  2. No.

  3. You could, because you happen to know that the koo function doesn't modify any const objects that are data members of A (because (a) the function body is empty and (b) A has no data members and (c) it's called on a non-const instance of A anyway). But don't do that.

  4. Mark koo as a const member function, same as foo.

Sign up to request clarification or add additional context in comments.

Comments

1

koo isn't declared as const, this indicates that it could change the object somehow, which isn't allowed on const objects. The signature of foo indicates that the current object (this) should be considered to be constant.

You'll need to specify a const variant of koo:

void koo() const {} void koo() {} 

3 Comments

And if the original koo doesn't change the object's state, it's not even necessary to overload: just add const to the original method.
@hvd Unless koo is a virtual function in which case changing to const will mean the base version isn't overridden any-more.
@PeterWood Good point. In that case, add const to the original method, and make the non-const override call the const version. Technically that's an overload, but you don't end up with two separate implementations.
0

if koo is declared not const (ie it modifies the internal state of the object) then indeed foo is not const.

Either make kooconst, foo not const, or if the object act like "with no state" but has internal variables that must be updated, then make these variables mutable.

mutable int m_accessCount; 

Comments

0

When you declare a function as const, you are saying "this function does never change the object". This allows you to use the function on const objects.

In your case, you are calling a non-const function from inside of a const one, which means that you cannot ensure the object will not change. This leads to an error, since the const on foo() implies the object must not change in any case.

Please avoid using const_cast, since it can cause UB if used improperly.

The best way to fix it is to provide a const version of koo(). Either write a non-modifying version of it, or (if it doesn't modify the object as it is) just add the const keyword.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.