2015-11-01 9 views
18

Per esempio:Possiamo omettere const sulle variabili locali nelle funzioni di constexpr?

constexpr int g() { return 30; }  

constexpr int f() 
{ 
    // Can we omit const? 
    const int x = g(); 
    const int y = 10; 

    return x + y; 
} 

C'è qualsiasi punto per sempre dichiarare le variabili locali in una funzione constexpr con const?

non sono constexpr funzioni con const variabili locali equivalenti a quelli senza const?

In altre parole, fa constexpr su una funzione imporre (implica) const sulle sue variabili locali?

+9

Non sono d'accordo con la vostra premessa che l'omissione di 'const' rende una funzione" più pulita ". Inoltre, no, non la penso così. Ma non sono "constexpr't. –

+3

Puoi persino [cambiarle] (http://ideone.com/L4Oa68)! (E la sua logica, non rende la funzione _not pure_) – Lol4t0

+2

@LeoHeinsaar Penso che tu intenda meno caratteri non bianchi, perché altrimenti può essere banalmente reso "più pulito" da quella definizione in un modo che sarà quasi universalmente interpretabile come illeggibile . – hvd

risposta

23

Gli stessi argomenti per dichiarare le variabili come const a non constexpr funzioni applicano anche ai constexpr funzioni:

  • Dichiarare una variabile const documenta il fatto che non potrà mai essere modificato. Ciò può in alcuni casi aiutare a rendere la funzione più leggibile.
  • Dichiarazione di variabile const affetti risoluzione di sovraccarico, e può rendere h(x) determinazione h diverso a seconda che x è const.

Naturalmente, nella direzione opposta, come indicato nei commenti già:

Anche in constexpr funzioni, variabili locali possono essere modificati. Se tali variabili vengono quindi modificate in modo che siano const, i tentativi di modificarle non verranno più accettati.

+0

Penso che questa sia una buona risposta. Senza pensarci troppo, potrebbe dare l'impressione che "constexpr" su una funzione imponga in qualche modo (implica) la costanza su tutto ciò che è al suo interno, comprese le variabili locali (perché, ad esempio, non si possono chiamare funzioni non-constexpr da esso). Grazie. –

+4

Ovviamente, non è possibile spostare le variabili locali const dal ritorno. Sono molto diffidente nei confronti dei locali per questo motivo. –

1

In generale, una funzione non può essere valutata in fase di compilazione e pertanto non può essere chiamata in un'espressione costante. La specifica di una funzione come constexpr indica che può essere utilizzata in espressioni costanti SE i suoi argomenti di input sono costanti. Ad esempio questo ...

constexpr int n = func(7); 

... deve essere valutato in fase di compilazione.

Questo è il significato di constexpr prima delle funzioni. Stando così le cose, non segue che le variabili locali all'interno della funzione non debbano essere specificate const.

16

In questo esempio particolare le variabili locali sarebbe meglio dichiarata constexpr, non const, perché possono essere calcolati in fase di compilazione:

constexpr int g() { return 30; }  

constexpr int f() 
{ 
    constexpr int x = g(); 
    constexpr int y = 10; 

    return x + y; 
} 

Quando f() viene chiamato in fase di esecuzione, senza la constexpr su x e , (con o senza const su x e) si sta dando al compilatore l'opzione per inizializzare x e y in fase di esecuzione anziché in fase di compilazione.Con il constexpr su x e y, il compilatore deve calcolare x e y al momento della compilazione, anche quando f() viene eseguito in fase di esecuzione.

In una diversa funzione, tuttavia, constexpr non può essere sempre utilizzato. Per esempio se f() e g() preso un parametro:

constexpr int g(int z) { return z+30; }  

constexpr int f(int z) 
{ 
    const int x = g(z); 
    constexpr int y = 10; 

    return x + y; 
} 

Ora x non possono essere contrassegnati constexpr perché z non può essere una fase di compilazione costante, e non v'è attualmente alcun modo per marcare come tale. Quindi in questo caso, contrassegnare xconst è il meglio che puoi fare.

+1

Sarebbe ragionevole richiedere implicitamente 'constexpr' su variabili locali che non sono cambiate? –

+0

@LeoHeinsaar: non ho paura. In questo esempio, cosa succede se 'g()' non è marcato 'constexpr'? In questo caso il risultato 'x' non può essere marcato' constexpr', e il compilatore ha i suoi diritti per calcolare 'g()' in fase di esecuzione. Forse 'g()' ha bisogno di fare una telefonata per ottenere il suo risultato ... –

+1

Se g() non è marcato 'constexpr', si suppone che debba compilare? Il modo in cui ho capito è che possiamo chiamare solo funzioni 'constexpr' dalle funzioni' constexpr' ... –

3

Non solo può, ma a volte si must (cioè se i cambiamenti variabili), ad esempio :

constexpr size_t f(size_t n) { 
    size_t val = 1; 
    if (n == 0) val++; 
    return val; 
} 
char arr0[f(0)] = {'a', 'x'}; 
char arr1[f(1)] = {'y'}; 

va bene in C++ 14.