Логическая константа в D

D имеет два типа констант: неизменяемые переменные - это те, которые были объявлены неизменяемыми, и всегда будет неизменным, тогда как переменные const - это просто версии объекта только для чтения.

Логическая константа - это когда функция помечена как const , но разрешает запись доступ к одной или нескольким переменным-членам. Обычно это используется для ленивых вычислений, например (в C ++)

struct Matrix
{
  double determinant() const
  {
    if ( m_dirty )
    {
      m_determinant = /* expensive calculation */;
      m_dirty = false;
    }
    return m_determinant;
  }

  void set(int i, int j, double x) { m_dirty = true; ...; }

  mutable bool m_dirty;
  mutable double m_determinant;
};

Здесь определитель () равен const , но все еще может изменять m_dirty и m_determinant из-за того, что они помечены как изменяемые .

D const (FAQ) говорит, что D2 не поддерживает логические константы из-за слабой гарантии что он обеспечивает, что является препятствием для написания параллельных программ и затрудняет определенную оптимизацию.

Я полностью понимаю проблему, но что, если нам нужна логическая константа ?

Рассмотрим приведенный выше случай с классом Matrix , но без кэширования (и без необходимости в логической константе). Также представьте, что этот класс используется во всей моей кодовой базе и в основном доступен через константные ссылки.

Теперь учтите, что профилирование показало, что функция определитель () является узким местом в коде, и, более того, к нему обычно обращаются многократно, а его значение редко меняется, т.е. кэширование, как указано выше, было бы идеальной оптимизацией.

Как я могу сделать это без логической константы? Перебирать всю мою кодовую базу с заменой константных ссылок на неконстантные ссылки не вариант (по очевидным причинам).

Какие у меня есть варианты (если есть)?

13
задан Peter Alexander 18 November 2010 в 21:09
поделиться