'auto' come segnaposto di argomento modello per un parametro di funzione


22

C ++ 20 consente l'utilizzo autoper il tipo di parametro della funzione.

Permette anche di utilizzare autocome segnaposto argomento modello (non simile, ma nello spirito del modello C ++ 17 <auto> in un certo senso) per il tipo di parametro funzione?

Quindi il seguente codice, pre C ++ 20:

template<typename First, typename Second>
void printPair(const std::pair<First, Second>& p) {
    std::cout << p.first << ", " << p.second;
}

Potrebbe essere scritto come:

void printPair(const std::pair<auto, auto>& p) {
    std::cout << p.first << ", " << p.second;
}

Si compila e funziona bene con l'implementazione sperimentale di GCC per concetti.

È una sintassi legittima con C ++ 20?


Da quello che ho sentito, il non vincolo auto si traduce direttamente in templatizzato typename XYZ, il che implicherebbe fortemente che si tratti della sintassi legittima. Pulito .
— Fureeish,

2
Nota che Clang non è d'accordo e che Clang e GCC hanno lo stesso disaccordo sul fatto che autosia consentito [](const std::pair<auto, auto>& p){}(con -std=c++2ao con -std=c++17).
— noce,


Grazie @DavisHerring - Ho corretto il testo
— Amir Kirsh il

Risposte:


17

Questa sintassi è valida nelle Specifiche tecniche dei concetti C ++, ma non in C ++ 20. Nei concetti C ++ 20, autoè consentito solo al livello superiore in un tipo di parametro di funzione. La regola rilevante è [dcl.spec.auto] paragrafo 2 :

Un segnaposto-tipo-specificatore del tipo-tipo di vincolo [opt] autopuò essere usato come decl-specificatore del decl-specificatore-seq di una dichiarazione di parametro di una dichiarazione di funzione o lambda-espressione e, se non è il auto l'identificatore di tipo che introduce un tipo-ritorno-trailing (vedi sotto), è un segnaposto di tipo di parametro generico della dichiarazione di funzione o lambda-espressione. [Nota: avere un segnaposto di tipo di parametro generico significa che la funzione è un modello di funzione abbreviato (9.3.3.5 [dcl.fct]) o lambda è un lambda generico (7.5.5 [expr.prim.lambda]). —Endola nota]

(Se si controlla la formulazione nella bozza di lavoro più recente al momento della stesura, si troverà una regola leggermente diversa. La regola di cui sopra è stata modificata dal numero centrale 2447 , che è stato votato nella bozza finale C ++ 20 a Praga riunione del comitato una settimana fa.)

Gli specificatori di decl in un parametro di funzione sono la sequenza iniziale di parole chiave e nomi di tipi all'inizio della dichiarazione del parametro. La regola di cui sopra consente autolì al livello superiore:

void f(auto x);

... ma solo come specificatore di decl . autonon è consentito se nidificato in uno specificatore di decl :

void f(std::vector<auto> x);

... e non è consentito anche altrove nel tipo di parametro:

void f(void (*p)(auto));

Wow, non lo sapevo! Il link CWG attualmente fornisce 404, quindi puoi spiegare brevemente la logica di questa restrizione?
— LF

Questo è assolutamente deludente.
— Fureeish,

1
Siamo spiacenti, il problema CWG e il suo cambio di formulazione non sono ancora pubblicamente visibili. La regola in questione è stata introdotta da open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1141r2.html e l'intenzione / logica doveva essere coerente con ciò che già consentivamo per lambda generici.
— Richard Smith,

4
@LF: Il problema CWG non è comunque rilevante: ha corretto un errore di formulazione che implicava che determinati usi di autoun tipo di ritorno finale fossero considerati come questo tipo di autoutilizzo.
— Davis Herring,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.