Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I const_cast "this" when a method only accepts Foo *const?

Tags:

c++

qt

I have a class Foo which is in a self referencing tree-like structure (minimally):

class Foo {
    public:
        // Gets this child's position relative to it's parent.
        int getPosition() const {
             return parent->indexOf(this);
        }

        int indexOf(const Foo *const child) const {
            return children.indexOf(child); // this line causes an error.
        }
    private:
        Foo *parent;
        QList<Foo *> children;
}

The line return children.indexOf(child) expects const T &value to be passed as per the QList docs, this resolves to Foo *const &value for my scenario.

In order for my getPosition() method to call my own indexOf() method it is required to have a signature of const Foo *child at minimum in order to pass this from a const method. (Since this is const Foo *const).

My code will not compile however as const Foo *const child cannot be cast to Foo *const child for QList::indexOf. Neither of my methods modify the object state so they should be const (i.e. I don't want to un-cost getPosition to receive a non-const this).

So the question is, how do I go from this in a const context (const Foo *const) to what QList::indexOf requires. Should I be const casting this inside getPosition since I know that my indexOf (and subsequent calls) will not mutate it?

Is there something else I should have done? Perhaps my design is faulty.

like image 477
Kasheen Avatar asked Jun 17 '13 20:06

Kasheen


People also ask

Is const_cast good practice?

As a common rule, it is very often considered a bad practice to use const_cast<>() in C++ code as it reveals (most of the time) a flaw in the design.

What is the use of const_cast in C++?

const_cast is one of the type casting operators. It is used to change the constant value of any object or we can say it is used to remove the constant nature of any object. const_cast can be used in programs that have any object with some constant value which need to be changed occasionally at some point.

How important is const correctness?

The benefit of const correctness is that it prevents you from inadvertently modifying something you didn't expect would be modified.

Why does const cast exist?

The whole purpose of const is to prevent you from modifying something, that's why your code generates an error. Adding in const_cast is basically telling the compiler to shut up, that you know what you're doing.


1 Answers

I think this is a perfectly reasonable use case for const_cast, however it's not this you need to const_cast, but child. In this case, QList::indexOf expects a constant pointer to a Foo (Foo* const) but child is a constant pointer to a constant Foo (const Foo* const). There is no implicit conversion from Foo* const to const Foo* const because that would remove the const-ness from the value being pointed to.

So, to fix your code I would change the line to

return children.indexOf(const_cast<Foo*>(child));

You know QList::indexOf is not going to modify whatever child points to, so this won't produce undefined behavior. I would however add a comment explaining why the const_cast is necessary.

like image 95
David Brown Avatar answered Oct 13 '22 00:10

David Brown