Обрабатывать вложенные std :: arrays как один плоский массив с цепочкой .data () - PullRequest
0 голосов
/ 22 мая 2018

Допустим, у меня есть этот маленький класс матрицы фиксированной размерности:

template<size_t M, size_t N>
struct MatMN { 
  std::array<std::array<double, N>, M> rows;
  double* begin() { return rows.data()->data(); } //The scary part
  double* end() { return begin() + M*N; }
  //const iterators, etc.
};

, и вместо использования вложенных циклов я реализую скалярное умножение (также тестирование на равенство, двоичную де / сериализацию и т. Д.) Примерно так::

template<size_t M, size_t N>
MatMN<M, N> operator*(double scalar, MatMN<M, N> mat) {
  for (double& x_ : mat) { x_ *= scalar; }
  return mat;
}

Можно ли рассматривать вложенные std::array s как единый плоский массив в стиле C, используя .data()->data()?

Могу ли я подвергнуться строгому наложению алиасов?вопрос?Или, может быть, неожиданное заполнение структуры в конце отдельных std::array s (то есть между строками матрицы)?До сих пор он работал нормально для меня (с GCC), но я знаю, что это мало что значит для C ++.

1 Ответ

0 голосов
/ 22 мая 2018

Можно ли рассматривать вложенные std :: arrays как один плоский массив в стиле C с помощью .data () -> data ()?

Нет.std::array допускается иметь заполнение в конце.Это означает, что может быть разрыв между тем, где один массив заканчивается, а другой начинается во вложенной структуре.получение указателя, как если бы вы сделали (если есть заполнение), приведет к тому, что вы получите доступ к этому заполнению, что даст вам неопределенные результаты.

Вместо сохранения матрицы в 2d std::array вы должны просто использовать 1d std::array.Таким образом, вы можете гарантировать, что все элементы находятся рядом друг с другом в памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...