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 (ie 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.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.