La risposta breve è che non solo è staticutile, ma è sempre abbastanza desiderabile.
Innanzitutto, nota che statice constexprsono completamente indipendenti l'uno dall'altro. staticdefinisce la durata dell'oggetto durante l'esecuzione; constexprspecifica che l'oggetto dovrebbe essere disponibile durante la compilazione. Compilazione ed esecuzione sono disgiunte e non contigue, sia nel tempo che nello spazio. Quindi, una volta compilato il programma, constexprnon è più rilevante.
Ogni variabile dichiarata constexprè implicitamente constma conste staticè quasi ortogonale (ad eccezione dell'interazione con static constnumeri interi).
Il C++modello a oggetti (§1.9) richiede che tutti gli oggetti diversi dai bit-field occupino almeno un byte di memoria e abbiano indirizzi; inoltre tutti questi oggetti osservabili in un programma in un determinato momento devono avere indirizzi distinti (paragrafo 6). Ciò non richiede al compilatore di creare un nuovo array nello stack per ogni invocazione di una funzione con un array const non statico locale, poiché il compilatore potrebbe rifugiarsi nel as-ifprincipio a condizione che possa dimostrare che nessun altro oggetto del genere può essere osservato.
Questo non sarà facile da dimostrare, sfortunatamente, a meno che la funzione non sia banale (ad esempio, non chiama alcuna altra funzione il cui corpo non è visibile all'interno dell'unità di traduzione) perché gli array, più o meno per definizione, sono indirizzi. Quindi nella maggior parte dei casi, l' const(expr)array non statico dovrà essere ricreato nello stack ad ogni invocazione, il che sconfigge il punto di poterlo calcolare al momento della compilazione.
D'altra parte, un static constoggetto locale è condiviso da tutti gli osservatori e inoltre può essere inizializzato anche se la funzione in cui è definito non viene mai chiamata. Quindi nessuno dei precedenti si applica e un compilatore è libero non solo di generare una sola istanza di esso; è libero di generarne una singola istanza nella memoria di sola lettura.
Quindi dovresti assolutamente usare static constexprnel tuo esempio.
Tuttavia, c'è un caso in cui non vorresti usare static constexpr. A meno che un constexproggetto dichiarato non sia utilizzato o dichiarato ODRstatic , il compilatore è libero di non includerlo affatto. È piuttosto utile, perché consente l'uso di constexprarray temporanei in fase di compilazione senza inquinare il programma compilato con byte non necessari. In tal caso, non si vorrebbe chiaramente utilizzarlo static, poiché staticè probabile che costringa l'oggetto a esistere in fase di esecuzione.
constda unconstoggetto, solo da un puntoconst X*che indica unX. Ma non è questo il punto; il punto è che gli oggetti automatici non possono avere indirizzi statici. Come ho detto,constexprcessa di essere significativo una volta terminata la compilazione, quindi non c'è nulla da buttare via (e molto probabilmente nulla, perché l'oggetto non è nemmeno garantito che esista in fase di esecuzione.)