Всегда ли безопасно заменять встроенный массив на std/ tr1/boost::array?

#c #arrays #visual-c #boost #refactoring

#c #массивы #visual-c #повышение #рефакторинг

Вопрос:

boost::array ( tr1 или std версия или) предлагают некоторые приятные дополнительные функции по сравнению со встроенным массивом.

До сих пор наша кодовая база содержит только встроенные массивы, например (составленные, но стиль совпадает):

 WORD m_lastReadFlags[FLAGS_MAX];
...
WORD flagBuffer[FLAGS_MAX];
if (getFlags(flagBuffer)) {
  memcpy(m_lastReadFlags, flagBuffer, sizeof(m_lastReadFlags));
  ...
 

Я думаю, вы поймете идею.

Теперь мой вопрос заключается в том, что для тех мест в коде, где удаление boost::array имело бы смысл (из-за других внесенных изменений), является array ли 100% сохранением семантики для встроенного массива? (Возможные ошибки компилятора в порядке — меня беспокоят только тихие изменения в поведении.)

То есть, можно ли переписать приведенный выше код (например) для использования:

 boost::array<WORD, FLAGS_MAX> m_lastReadFlags;
 

и memcpy (возможно, адаптированный для использования c_array() или data() ) и другой доступ, подобный массиву, останется прежним? Да, конечно, я мог бы также заменить локальный буфер массивом и удалить memcpy или использовать std::copy или что-то в этом роде, но суть этого вопроса заключается в совместимости встроенных массивов и класса array .


Обновление: Одна вещь, которая меня особенно беспокоит, — это места (например, в memcpy случае), где встроенные массивы используются в качестве указателей. Все ли события будут пойманы компилятором / обработаны правильно?

Как насчет назначения?

 T arr1[N]; // or array<T, N>
T arr2[N]; // or array<T, N>
T* p1;
...
// Note, not all combinations will compile:
arr1 = arr2;
p1 = arr1;
arr2 = p1;
...
 

Ответ №1:

Да, это должно быть хорошо, поскольку array класс является именно оболочкой для автоматического массива. Он имеет тот же синтаксис доступа с квадратными скобками, и если вам нужно добраться до указателя, вы знаете, как это сделать. Вы даже можете использовать std::copy везде и использовать итераторы; есть вероятность, что это будет реализовано memcpy в любом случае.

array Класс имеет агрегированный тип (без нетривиальных конструкторов / деструкторов / присваиваний), поэтому вы можете инициализировать его с помощью традиционного агрегатного (фигурного) инициализатора, как обычный массив.