Короткий ответ заключается в том, что это не только staticполезно, но и всегда будет желанным.
Во-первых, обратите внимание, что staticи constexprполностью независимы друг от друга. staticопределяет время жизни объекта во время выполнения; constexprуказывает, что объект должен быть доступен во время компиляции. Компиляция и исполнение являются несвязанными и несмежными как во времени, так и в пространстве. Поэтому, как только программа скомпилирована, constexprона больше не актуальна.
Каждая объявленная переменная constexprнеявно, constно constи staticпочти ортогональна (за исключением взаимодействия с static constцелыми числами.)
C++Объектная модель (§1.9) требует , чтобы все объекты, кроме битовых полей занимают по меньшей мере , один байты памяти и имеют адреса; кроме того, все такие объекты, наблюдаемые в программе в данный момент, должны иметь разные адреса (пункт 6). Это совсем не требует, чтобы компилятор создавал новый массив в стеке для каждого вызова функции с локальным нестатическим константным массивом, потому что компилятор мог бы укрыться в as-ifпринципе, при условии, что он может доказать, что никакой другой такой объект не может быть наблюдаемый.
К сожалению, доказать это будет непросто, если только функция не является тривиальной (например, она не вызывает никакой другой функции, тело которой не видно внутри единицы преобразования), поскольку массивы, более или менее по определению, являются адресами. Таким образом, в большинстве случаев нестатический const(expr)массив нужно будет заново создавать в стеке при каждом вызове, что лишает его возможности вычислять его во время компиляции.
С другой стороны, локальный static constобъект является общим для всех наблюдателей, и, кроме того, он может быть инициализирован, даже если функция, в которой он определен, никогда не вызывается. Таким образом, ничего из вышеперечисленного не применимо, и компилятор может не только генерировать только один его экземпляр; он может генерировать один экземпляр в хранилище только для чтения.
Так что вы обязательно должны использовать static constexprв своем примере.
Тем не менее, есть один случай, когда вы не хотите использовать static constexpr. Если constexprобъявленный объект не используется ODR или не объявлен static, компилятор может вообще не включать его. Это очень полезно, поскольку позволяет использовать временные constexprмассивы во время компиляции, не загрязняя скомпилированную программу ненужными байтами. В этом случае вы явно не захотите использовать static, поскольку static, вероятно, вынудите объект существовать во время выполнения.
constотconstобъекта, только изconst X*которых указывает наX. Но дело не в этом; Дело в том, что автоматические объекты не могут иметь статические адреса. Как я уже говорил,constexprперестает быть значимым , как только компиляция закончится, так что нет ничего разбрасывать (и , вполне возможно , вообще ничего, так как объект не гарантируется даже существовать во время выполнения.)