2015-07-21 1 views
1

Неужели по-прежнему не определено поведение, чтобы исключить const из указателя на объект, если после трансляции вызываются только методы const?Можно ли исключить const, если никогда не называть какие-либо неконстантные методы?

Я пытаюсь реализовать как итератор и const_iterator для класса, где разыменованного итератора является прокси-объект с небольшим количеством состояния и указатель на родительский объект (упрощенный ниже)

Хотя сопзЬ квалифицированный прокси только вызывает методы const для родителя, он по-прежнему требует указателя-не-const в конструкторе.

class query { 
    public: 
     int get (int r, int c) const; 
     void set (int r, int c, int v); 

     class iterator { 
     iterator (query *q, int r) : m_qry(q), m_row(r) {} 
     row operator* const() { return row(m_qry, m_row); } 

     query *m_qry; 
     int m_row; 
     }; 

     class const_iterator { 
     const_iterator (const query *q, int r) : m_qry(q), m_row(r) {} 

     const row operator* const() { 
      // protected constructor for row needs cast 
      return row(const_cast<query *>(m_qry), m_row); 
     } 

     const query *m_qry; 
     int m_row; 
     }; 

     iterator  begin() { return iterator(this, 0); } 
     const_iterator begin() { return const_iterator(this, 0); } 
}; 

class row { 
    friend query; 

    public: 
     int get (int col) const { 
     // can be called by both row and const row 
     return m_qry->get(m_row, col); 
     } 

     void set (int col, int v) { 
     // cannot be called for const row 
     return m_qry->set(m_row, col, v); 
     } 

    protected: 
     row (query *q, int row) : m_qry(q), m_row(r) {} 

    private: 
     query *m_qry; 
     int m_row; 
}; 

Я бы предпочел не использовать разные классы для разных итераторов, поскольку для этого потребуется значительное дублирование кода.

Если это невозможно, есть ли другие альтернативные образцы дизайна с хорошей производительностью?

+0

однако с вышеупомянутой конструкцией компилятор укусит вас через конструктор копирования по умолчанию, принимающий ссылку на константу и создающий неконстантный объект – patchsoft

ответ

2

В методе const указатель this представляет собой тип const.

Так что, если он неявно отбрасывается в const, поведение корректно определено.