2015-07-14 12 views
5

ho sono imbattuto nuovo C++ 14 firma per std::max funzione:difficoltà a capire C++ 14 Relaxed restrizioni constexpr

template< class T > 
const T& max(const T& a, const T& b); // (C++11) 

template< class T > 
constexpr const T& max(const T& a, const T& b);// (C++14) 

ho letto circa restrizioni constexpr Relaxed proposta di C++ 14 ma io sono ancora non capisco perché questo valore di ritorno funzione può essere constexpr

Esempio:

std::vector<int> a, b; 
//This does not compile but as my understadnding of `constexpr` this should 
int array[std::max(a.size(), b.size()]; (1) 
//This is trivial use that does compile 
int array[std::max(1,2)]; (2) 

Quando si chiama std::max in (1) constexpr viene ignorato?

+0

'constexpr' qui non significa che il valore restituito dalla funzione è' constexpr'. Significa che la funzione è 'constexpr'. (Simile a come 'static int x();' non significa che 'x' restituisce un int statico). –

risposta

10

Il problema di base non è direttamente correlato alle regole rilassate di constexpr, una funzione di constexpr è solo un'espressione costante se gli argomenti sono espressioni costanti. Nel secondo caso:

int array[std::max(1,2)]; 

questo funziona perché i letterali integer sono in effetti espressioni costanti.

C++ 11 era più specifico in questo caso, il progetto standard C++ 11 nella sezione 5.19[expr.const] stabilisce i casi in cui una sotto-espressione non è considerato un'espressione costante e contiene la seguente:

invocazione di una funzione constexpr con argomenti che, quando sostituito per sostituzione funzione chiamata (7.1.5), non producono un'espressione costante;

in C++ 14 questo paragrafo è stato rimosso e abbiamo la seguente eccezione:

invocazione di una funzione diversa da un costruttore constexpr per una classe letterale, una funzione constexpr, o un invocazione implicita di un distrugger triviale (12.4) [Nota: la risoluzione di sovraccarico (13.3) è applicata come di consueto -end note];

e dobbiamo utilizzare il resto delle regole per quanto riguarda gli argomenti (sottoespressioni).

Nel primo caso:

int array[std::max(a.size(), b.size()]; 

std::vector::size non è contrassegnato constexpr e quindi cade sotto l'eccezione sopra citata.

noti inoltre che nella sezione 7.1.5[dcl.constexpr] abbiamo la seguente:

Una chiamata a una funzione constexpr produce lo stesso risultato di una chiamata a una funzione non constexpr equivalente tutti gli aspetti tranne per il fatto che una chiamata a una funzione constexpr può apparire in un'espressione costante.

Passare argomenti a una funzione di constexpr che non sono espressioni costanti significa solo che l'espressione non è disponibile per gli usi in contesti che richiedono un'espressione costante.

Come sottolinea dyp che std::max non è stato fatto constexpr in C++ 11 a causa a varie questioni, tra cui probabilmente comitato essendo tempo conservatore e limitato, possiamo vedere alcune delle questioni coinvolte nella N3039. essendo dimenticato vedere N3856 che dice:

Questo breve documento propone di rendere le funzioni min standard max constexpr. Erano in cima alla lista dei casi motivanti per al- che riducono i parametri di riferimento per le funzioni di constexpr in C++ 11. Essi sono stati dimenticati dopo la modifica della lingua di base è stata accettata

Per riferimento sappiamo che 1 e 2 sono costanti espressione dalla sezione 5.19 che dice:

Un'espressione costante letterale è un nucleo prvalue un'espressione costante di tipo letterale, ma non di puntatore. Un'espressione costante integrale è un'espressione costante letterale di tipo di enumerazione integrale o senza ambito. [...]

+0

Ho pensato che la funzione dichiarata come 'constexpr' possa essere invocata solo con valori che possono essere calcolati durante la compilazione altrimenti sarà un errore in fase di compilazione ... –

+0

@AlejandroFreeman risposta aggiornata –

+0

@dip sai che avevo trovato [ lwg 2350] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3893.html#2350) ma ero confuso perché passava da wp -> open e non potevo capire perché –

Problemi correlati