introduzione
constexpr
non è stato introdotto come un modo per dire all'implementazione che qualcosa può essere valutato in un contesto che richiede un'espressione costante ; implementazioni conformi sono state in grado di dimostrarlo prima di C ++ 11.
Qualcosa che un'implementazione non può dimostrare è il intento di un certo codice:
- Cosa vuole esprimere lo sviluppatore con questa entità?
- Dovremmo consentire ciecamente al codice di essere utilizzato in un'espressione costante , solo perché sembra funzionare?
Cosa sarebbe il mondo senza constexpr
?
Supponiamo che tu stia sviluppando una libreria e ti rendi conto che vuoi essere in grado di calcolare la somma di ogni numero intero nell'intervallo (0,N]
.
int f (int n) {
return n > 0 ? n + f (n-1) : n;
}
La mancanza di intenti
Un compilatore può facilmente dimostrare che la funzione sopra è richiamabile in a un'espressione costante se l'argomento passato è noto durante la traduzione; ma non hai dichiarato questo come un intento - è semplicemente successo.
Ora arriva qualcun altro, legge la tua funzione, fa la stessa analisi del compilatore; " Oh, questa funzione è utilizzabile in un'espressione costante!" e scrive il seguente pezzo di codice.
T arr[f(10)]; // freakin' magic
L'ottimizzazione
Tu, come sviluppatore di librerie "fantastico" , decidi che f
dovrebbe essere memorizzato nella cache il risultato quando viene invocato; chi vorrebbe calcolare ripetutamente lo stesso insieme di valori?
int func (int n) {
static std::map<int, int> _cached;
if (_cached.find (n) == _cached.end ())
_cached[n] = n > 0 ? n + func (n-1) : n;
return _cached[n];
}
Il risultato
Introducendo la tua stupida ottimizzazione, hai semplicemente rotto ogni utilizzo della tua funzione che si trovava in un contesto in cui era richiesta un'espressione costante .
Non hai mai promesso che la funzione fosse utilizzabile in un'espressione costante e senza di constexpr
essa non ci sarebbe modo di fornire tale promessa.
Quindi, perché ne abbiamo bisogno constexpr
?
L'uso principale di constexpr è dichiarare l' intenzione .
Se un'entità non è contrassegnata come constexpr
- non è mai stata pensata per essere utilizzata in un'espressione costante ; e anche se lo è, facciamo affidamento sul compilatore per diagnosticare tale contesto (perché ignora il nostro intento).
constexpr
? In tal caso, posso vedere un utilizzo.