I costruttori di modelli di classe possono avere un elenco di parametri di modello ridondante in c ++ 20
Per quanto ne so, il codice seguente :
template<typename T>
struct S {
S<T>();
};
è ben formato, anche se il <T>
nella dichiarazione del costruttore è ridondante.
Tuttavia, su gcc trunk (ma non su gcc10.2), con -std=c++20
questo viene visualizzato un errore:
error: expected unqualified-id before ')' token
3 | S<T>();
^
Il codice viene compilato su clang trunk con -std=c++20
. È un bug o è un cambiamento radicale in c ++ 20 che deve ancora essere implementato in tutti i compilatori?
Risposte
In effetti c'è stato un cambiamento. È documentato nella sezione compatibilità della bozza C ++ 20.
[diff.cpp17.class]
2 Sottoclausole interessate : [class.ctor] e [class.dtor]
Modifica : un simple-template-id non è più valido come dichiaratore-id di un costruttore o distruttore.
Motivazione : rimuovere l'opzione potenzialmente soggetta a errori per la ridondanza.
Effetto sulla funzionalità originale : il codice C ++ 2017 valido potrebbe non essere compilato in questo standard internazionale. Per esempio:template<class T> struct A { A<T>(); // error: simple-template-id not allowed for constructor A(int); // OK, injected-class-name used ~A<T>(); // error: simple-template-id not allowed for destructor };
Nello specifico, la formulazione delta è questa:
n4659 - Bozza standard C ++ 17 - [class.ctor]
1 I costruttori non hanno nomi. In una dichiarazione di un costruttore, il dichiaratore è un dichiaratore di funzione della forma
ptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq
dove il ptr-dichiarator consiste esclusivamente di un'espressione id, un attributo-specificatore-seq opzionale e parentesi circostanti opzionali e l'espressione id ha una delle seguenti forme:
- in una dichiarazione di membro che appartiene alla specifica di membro di una classe ma non è una dichiarazione di amicizia, l'espressione id è il nome di classe inserito della classe che racchiude immediatamente;
- in una dichiarazione di membro che appartiene alla specifica di membro di un modello di classe ma non è una dichiarazione di amicizia, l'espressione id è un nome di classe che nomina l'istanza corrente del modello di classe che racchiude immediatamente; o
n4861 - Bozza standard C ++ 20 - [class.ctor]
1 Un costruttore viene introdotto da una dichiarazione il cui dichiaratore è un dichiaratore di funzione ([dcl.fct]) della forma
ptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq
dove il ptr-dichiarator consiste esclusivamente di un'espressione id, un attributo-specificatore-seq opzionale e parentesi circostanti opzionali e l'espressione id ha una delle seguenti forme:
- in una dichiarazione di membro che appartiene alla specifica di membro di una classe o di un modello di classe ma non è una dichiarazione di amicizia ([class.friend]), l'espressione id è il nome di classe inserito ([class.pre]) dell'entità che lo racchiude immediatamente o
Come puoi vedere, la formulazione è cambiata. C ++ 20 ora richiede il nome della classe inserito quando si dichiara un costruttore per un modello di classe. S<T>
è un semplice ID modello che nomina una specializzazione. All'interno di un modello, il nome della classe inserito è semplicemente S
.
Questo fa parte dell'affrontare CWG 2237 .