Будет ли это правильным использованием reinterpret_cast или есть какой-то лучший подход для решения проблемы.
Node<T>* front_;
Iterator<const T> GetConstIterator() const {
return Iterator<const T>(reinterpret_cast<Node<const T>*>(front_));
}
Iterator<T> GetIterator() {
return Iterator<T>(front_);
}
Конструктор итератора определяется следующим образом.
template<class T>
class Iterator {
explicit Iterator(Node<T>* const node) : node_(node) {}
...
}
Вам нужно будет сделать вашу константную версию итератора конструируемой из неконстантного узла. Затем я бы переписал геттеры для большей совместимости с STL:
Iterator<const T> begin() const { return Iterator<const T>(front_); }
Iterator<T> begin() { return Iterator<T>(front_); }
Все, что вам нужно сделать — это скомпилировать эту первую версию. Кастинг здесь не работает Node<T>
не будет связано с Node<const T>
,
Недопустимо использовать reinterpret_cast для отбрасывания константности. Вам нужно использовать const_cast для этого. Вы мог использование reinterpret_cast
добавить постоянство, но const_cast
является более правильным и более очевидным для будущих сопровождающих.
Из §5.2.10 Переинтерпретировать приведение, p2:
Оператор reinterpret_cast не должен отбрасывать константу (5.2.11).
Выражение целого, перечисления, указателя или указателя на член
тип может быть явно преобразован в свой собственный тип; такой бросок дает
значение его операнда.
Действительно, конструктор Node<const T>
должен быть в состоянии сделать это неявно, и приведение не должно даже быть необходимым.
Неопределенность возникает из вашей функции:
Iterator<T> GetIterator() const {
return Iterator<T>(front_);
}
Вы не должны возвращать итератор, который может изменить контейнер как метод const. Этот метод не должен иметь const-квалификатора.
Вы должны просто иметь:
Iterator<const T> GetIterator() const {
return Iterator<const T>(front_);
}
Iterator<T> GetIterator() {
return Iterator<T>(front_);
}