Проблема возникает из-за того, как стандарт определяет тип массива (8.3.4 [dcl.array]):
Объект типа массива содержит непрерывно выделенный непустой набор N подобъекты типа T.
, но в нем явно не говорится, что непрерывный выделенный набор объектов одного типа может использоваться как массив.
По соображениям совместимости все компиляторы I Знайте, примите эту взаимность, но с педантичной точки зрения она не определена явно в стандарте и является неопределенным поведением.
Обоснование невзаимности заключается в том, что программа должна представлять модель. А в модели у объекта нет причин быть членом или более чем одним массивом одновременно. Так что стандарт этого не позволяет. Фактически, все (реальные) варианты использования, с которыми я когда-либо сталкивался для обработки 2D-массива, как если бы это был 1D-массив, были просто причинами оптимизации низкого уровня. А в современном C ++ программисту не следует заботиться о низкоуровневой оптимизации, а позволить компилятору это делать. это был 1D, вы должны спросить себя, в чем причина. Если вы используете устаревший код, не беспокойтесь об этом: компиляторы в настоящее время принимают его и даже в будущем, вероятно, продолжат работу, даже за счет специальных опций.
Но если вы пишете новый код, вам следует попробовать подняться на одну ступеньку выше (или назад) и задаться вопросом, что это означает на уровне модели . В большинстве случаев вы обнаружите, что массив изначально является 1D или 2D, но не одновременно. Как только это будет сделано, если производительность не критична, старайтесь всегда обрабатывать соответствующим образом . Или, что еще лучше, попробуйте использовать контейнеры из стандартной библиотеки вместо необработанных массивов.
Если вы используете критически важный для производительности код, в котором говорится, что любой смежный выделенный набор объектов является массивом, дает важное преимущество, сделайте это и задокументируйте его для будущих сопровождающих. Но делать это только после профилирования ...