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. [...]
'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). –