2015-04-03 18 views
25

Ho qualche problema con constexpr. Il libro C++ Primer mostra una riga di codice:L'uso della funzione constexpr prima della definizione non riesce

constexpr int sz = size(); // only size() is a constexpr function 
          // this code is right 

Tuttavia il libro non dà un esempio specifico. Così provo il seguente codice da me:

#include <iostream> 
constexpr int fun(); 
int main() 
{ 
    constexpr int f = fun(); 
    std::cout << f << std::endl; 
} 
constexpr int fun() 
{ 
    return 3; 
} 

Ma il mio compilatore detto fun() non è definito.

Se cambio constexpr in const, funziona bene, e se cambio il mio codice per definire la funzione constexpr prima dell'uso:

#include <iostream> 
constexpr int fun() 
{ 
    return 3; 
} 
int main() 
{ 
    constexpr int f = fun(); 
    std::cout << f << std::endl; 
} 

funziona anche bene. Qualcuno può dirmi perché?

+1

Che compilatore usi? – kvorobiev

+0

@kvorobiev clang, linux – icecity96

+0

Quale versione di clang? – kvorobiev

risposta

15

Una funzione constexpr NON deve essere definita prima del suo primo utilizzo, tuttavia il risultato di qualsiasi chiamata effettuata prima della definizione non è un'espressione costante.

Fonte: C++ progetti di n4296 standard, sezione 5.20:

A condizionale espressionee è un nucleo costante espressione a meno che la valutazione del e, seguendo le regole della macchina astratta, sarebbe valutare una delle seguenti espressioni:

  • this, se non in una funzione o un constexprconstexpr co nstructor che viene valutato come parte di e;
  • un'invocazione di una funzione diversa da un costruttore constexpr per una classe letterale, una funzione constexpr o un'invocazione implicita di un distruttore banale [Nota: la risoluzione di sovraccarico viene applicata come solito - nota finale];
  • invocazione di una funzione non definita constexpr o un costruttore non definito constexpr;
  • ...

versione dal progetto 3485 (sezione 5.19):

A condizionale espressione- è un nucleo costante espressione meno che non comporti una delle seguenti come una sottoespressione potenzialmente valutata, ma le sottoespressioni delle operazioni logiche AND, OR logiche e condizionali che non sono valutate non sono considerate [Nota: un operatore sovraccarico richiama una funzione.- nota end]:

  • this [Nota: quando si valuta un'espressione costante, sostituzione invocazione funzione sostituisce ogni occorrenza di this in una funzione constexpr membro con un puntatore all'oggetto classe. - nota finale];
  • un'invocazione di una funzione diversa da un costruttore constexpr per una classe letterale o una funzione constexpr [Nota: la risoluzione di sovraccarico viene applicata come di consueto - nota finale];
  • una chiamata di una indefinita constexpr funzione o un indefinito constexpr costruttore
  • ...

L'esempio int x2 = s. t(); in n2235 effettivamente diventato valida a causa delle modifiche apportate prima normalizzazione. Tuttavia, constexpr int x2 = s. t(); rimane un errore.

+0

n4296 è una bozza di C++ Standart. I compilatori lo hanno già supportato? – kvorobiev

+1

@kvorobiev: sto citando da una bozza perché è pubblica. La regola è stata introdotta alcune bozze prima e fa parte dello standard ufficiale. –

+0

@kvorobiev puoi guardare N3337 5.19/2, che è fondamentalmente la versione finale dello standard C++ 11. g ++/clang ++ sono compatibili con C++ 11 (con piccole eccezioni) – vsoftco

3

Una funzione di espressione costante deve essere definita prima del primo utilizzo. Vedi questo paper, fine della sezione 4.1.

+0

Quindi il libro è in errore? Forse alcuni compilatori accettano questa sintassi nonostante non sia consentita dallo standard? –

+0

In base a questa [tabella] (http://wiki.apache.org/stdcxx/C++0xCompilerSupport) alcuni compilatori supportano constexpr ora e dubito che uno di essi supporti questa sintassi. – kvorobiev

+0

@kvorobiev ma i compilatori più importanti sono abbastanza pronti per C++ 11, in particolare g ++/clang ++. MSVC non ancora, ma per arrivarci. – vsoftco

Problemi correlati