Должен ли я const_cast "this", когда метод принимает только Foo * const?

У меня есть класс Foo, который находится в древовидной структуре с самостоятельной ссылкой (минимально):

class Foo {
    public:
        // Gets this child position relative to it 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;
}

Линия return children.indexOf(child) ожидает передачи const T &value в соответствии с QList docs, это разрешает Foo *const &value для моего сценария.

Чтобы мой метод getPosition() вызывал мой собственный метод indexOf(), требуется, чтобы подпись const Foo *child была минимальной, чтобы передать this из метода const. (Так как это const Foo *const).

Мой код не будет компилироваться, однако const Foo *const child не может быть добавлен в Foo *const child для QList::indexOf. Ни один из моих методов не изменяет состояние объекта, поэтому они должны быть const (т.е. Я не хочу нести расходы getPosition для получения неконстантного this).

Итак, вопрос в том, как мне перейти от this в контексте const (const Foo *const) к тому, что требуется QList::indexOf. Должен ли я быть const cast this внутри getPosition, так как я знаю, что мой indexOf (и последующие вызовы) не будет мутировать его?

Есть ли что-то еще, что я должен был сделать? Возможно, мой дизайн неисправен.

Ответ 1

Я думаю, что это вполне разумный вариант использования для const_cast, однако это не this вам нужно const_cast, но child. В этом случае QList::indexOf ожидает постоянный указатель на Foo (Foo* const), но child является постоянным указателем на константу Foo (const Foo* const). Нет никакого неявного преобразования из Foo* const в const Foo* const, потому что это приведет к удалению константы из указанного значения.

Итак, чтобы исправить ваш код, я бы изменил строку на

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

Вы знаете, что QList::indexOf не собирается изменять все, на что указывает child, поэтому это не приведет к поведению undefined. Однако я бы добавил комментарий, объясняющий, почему нужен const_cast.