Non molto tempo fa richiede espressioni (la frase introdotta dalla seconda richiede) non era consentita nelle espressioni di vincolo (la frase introdotta dalla prima richiede). Potrebbe apparire solo nelle definizioni dei concetti. In realtà, questo è esattamente ciò che viene proposto nella sezione di quel documento in cui appare tale affermazione.
Tuttavia, nel 2016, c'era una proposta per allentare tale restrizione [Nota del redattore: P0266 ]. Nota la barratura del paragrafo 4 nella sezione 4 del documento. E così è nato richiede richiede.
A dire il vero, non avevo mai implementato quella restrizione in GCC, quindi era sempre stato possibile. Penso che Walter possa averlo scoperto e trovato utile, portando a quel documento.
Per evitare che qualcuno pensasse che non fossi sensibile alla scrittura richiede due volte, ho passato un po 'di tempo a cercare di determinare se ciò potesse essere semplificato. Risposta breve: no.
Il problema è che ci sono due costrutti grammaticali che devono essere introdotti dopo un elenco di parametri del modello: molto comunemente un'espressione di vincolo (come P && Q
) e occasionalmente requisiti sintattici (come requires (T a) { ... }
). Questa si chiama espressione richiesta.
Il primo richiede introduce il vincolo. Il secondo richiede introduce l'espressione obbligatoria. Questo è solo il modo in cui la grammatica si compone. Non lo trovo affatto confuso.
Ho provato, ad un certo punto, a comprimerli in un unico requisito. Sfortunatamente, ciò porta ad alcuni problemi di analisi seriamente difficili. Non si può facilmente dire, ad esempio se un (
after richiede richiede una sottoespressione nidificata o un elenco di parametri. Non credo che ci sia una perfetta disambiguazione di quelle sintassi (vedere la logica per una sintassi di inizializzazione uniforme; anche questo problema è presente).
Quindi fai una scelta: make richiede di introdurre un'espressione (come fa ora) o di introdurre un elenco parametrico di requisiti.
Ho scelto l'approccio attuale perché la maggior parte delle volte (come in quasi il 100% delle volte), voglio qualcosa di diverso da un'espressione richiesta. E nel caso estremamente raro che volevo un'espressione obbligatoria per i vincoli ad hoc, non mi dispiace davvero scrivere la parola due volte. È un chiaro indicatore che non ho sviluppato un'astrazione sufficientemente solida per il modello. (Perché se avessi avuto, avrebbe un nome.)
Avrei potuto scegliere di fare in modo che i requisiti introducessero un'espressione obbligatoria. In realtà è peggio, perché praticamente tutti i tuoi vincoli inizierebbero ad apparire così:
template<typename T>
requires { requires Eq<T>; }
void f(T a, T b);
Qui, il secondo requisito è chiamato requisito nidificato; valuta la sua espressione (non viene valutato altro codice nel blocco dell'espressione richiesta). Penso che questo sia molto peggio dello status quo. Ora, puoi scrivere richiede due volte ovunque.
Avrei anche potuto usare più parole chiave. Questo è un problema a sé stante --- e non si tratta solo di spargimento di biciclette. Potrebbe esserci un modo per "ridistribuire" le parole chiave per evitare la duplicazione, ma non ho pensato seriamente. Ma questo non cambia davvero l'essenza del problema.
noexcept(noexcept(...))
.