Qual è la differenza tra una classe modello e un modello di classe?


88

Qual è la differenza tra una classe modello e un modello di classe?

Risposte:


127

Questo è un punto comune di confusione per molti (inclusa la pagina di programmazione generica su Wikipedia, alcuni tutorial C ++ e altre risposte su questa pagina). Per quanto riguarda il C ++, non esiste una "classe modello", esiste solo un "modello di classe". Il modo di leggere questa frase è "un modello per una classe", al contrario di un "modello di funzione", che è "un modello per una funzione". Di nuovo: le classi non definiscono modelli, i modelli definiscono classi (e funzioni). Ad esempio, questo è un modello , in particolare un modello di classe , ma è non è una classe :

template<typename T> class MyClassTemplate
{ 
    ...
};

La dichiarazione MyClassTemplate<int> è una classe, o pedanticamente, una classe basata su un modello. Non ci sono proprietà speciali di una classe basata su un modello rispetto a una classe non basata su un modello. Le proprietà speciali sono del modello stesso .

La frase "classe modello" non significa nulla, perché la parola "modello" non ha alcun significato come aggettivo quando applicata al sostantivo "classe" per quanto riguarda C ++. Implica l'esistenza di una classe che è (o definisce) un modello , che non è un concetto che esiste in C ++.

Capisco la confusione comune, poiché probabilmente si basa sul fatto che le parole compaiono nell'ordine "classe modello" nella lingua reale, che è tutta un'altra storia.


+1. A volte è utile per qualsiasi motivo distinguere l '"origine" di una classe, nel qual caso puoi ragionevolmente usare il termine "classe modello" - ma per le ragioni che hai fornito, è una buona idea definire attentamente cosa intendi con questo .
j_random_hacker

1
@j_random_hacker - vedi la risposta di litb di seguito, ma in breve, il termine preferito è "specializzazione del modello di classe"
Non sicuro,

@Not Sure: Beh, in realtà trovo la "specializzazione del modello di classe" leggermente ambigua, poiché può anche riferirsi al processo di definizione di una specializzazione esplicita o parziale per un modello - qualcosa che non è necessario per produrre una vera "classe". :) IMHO "istanziazione del modello di classe" è il termine più chiaro.
j_random_hacker

2
@j_random_hacker: C'è un termine appropriato per questo - "specializzazione di modelli di classe esplicita" e "specializzazione di modelli di classe esplicita parziale". Ingombrante, ma non ambiguo :)
Non so

1
−1 I termini significano ciò che significano per le persone che utilizzano i termini. Iniziare ad analizzare i significati letterali non ha senso. Provalo con quasi tutti gli altri termini della vita quotidiana o dell'ingegneria. Riassumendo, questa risposta è sciocca. La risposta di SHH , citando Bjarne, è OK.
Saluti e salute. - Alf

15

Bjarne Stroustrup, il creatore di C ++, afferma nel suo libro The C ++ Programming Language 4th edition , 23.2.1 Defining a Template:

Ci sono persone che fanno distinzioni semantiche tra i termini modello di classe e classe modello . Io non; sarebbe troppo sottile: considera questi termini intercambiabili. Allo stesso modo, considero il template della funzione intercambiabile con la funzione template .


13

La differenza è che il termine "classe modello" semplicemente non esiste nello standard C ++. È un termine usato principalmente da persone che pensano che il termine "modello di classe" sia fonte di confusione (come le società Qt Nokia e precedentemente Trolltech).

Lo Standard non ne ha il concetto, quindi spetta ad altre persone fare la differenza. Alcune persone lo usano come sinonimi, e altri dicono che il termine "classe modello" si riferisce a un modello di classe istanziato o esplicitamente specializzato, il che lo renderebbe equivalente al termine "specializzazione modello di classe". Storicamente, aveva questo significato. Il Manuale di riferimento annotato definisce a pagina 343

Una classe generata da un modello di classe è chiamata classe modello, così come una classe specificatamente definita con un nome-classe-modello come nome

Il nome-classe-modello non-terminale è equivalente all'id- modello non-terminale usato nello standard odierno e si riduce template-name < arguments >.


Per familiarizzare con i termini odierni, che è più importante che usare vecchi termini dubbi

// (1) defines a class template
template<typename T> class A { }; 

// (2) defines a class template explicit specialization 
template<> class A<int> { };

// (3) defines a class template partial specialization
template<typename T> class A<T*> { };

// (4) explicitly instantiates A<char>. 
template class A<char>;

// (5) implicitly instantiates A<short> (because of the member declaration)
struct D { A<short> a; };
  • L'ARM ha chiamato la classe (2) e le classi generate da (4) e (5) una classe modello . Non sono sicuro che l'ARM conoscesse già le specializzazioni parziali. Ma se è così (3) non è stata chiamata classe template, perché (3) non definisce una classe, ma definisce un template.
  • L'attuale Standard chiama la classe (2) e quelle generate dalle specializzazioni dei modelli di classe (4) e (5) . E (3) è chiamata specializzazione parziale , in contrapposizione a una specializzazione esplicita . A volte chiama anche (3) una specializzazione (3.2 / 5 - tuttavia con collegamenti incrociati chiarificatori), anche se trovo che questo non sia del tutto chiaro per me, poiché definisce una "specializzazione" come una "classe, funzione o classe membro ", che (3) non soddisfa.

3
Hehe. Sì e anche molti altri contribuiscono ancora a quel set. In particolare la C ++ Faq lite e la documentazione Qt. L'autore della faq lite mi ha detto in una mail che vuole inserire un altro elemento di FAQ spiegando che l'uso della parola "specializzazione" è migliore poiché causa meno confusione (usando "specializzazione esplicita" per il tipo di specializzazione scritta dall'utente, poi). I ragazzi di Qt mi hanno detto che non vogliono usare il termine "modello di classe" .... lo trovano troppo "innaturale". Peccato.
Johannes Schaub - litb

@ JohannesSchaub-litb: L'ARM è stato scritto da Bjarne Stroustrup e Margaret Ellis, all'incirca nel 1991 IIRC. La tua citazione da ARM contraddice la citazione di SHH dalla quarta edizione di TCPPL di Bjarne . Quindi è positivo che tu faccia una distinzione tra la vecchia (pre-standard) e la terminologia attuale.
Saluti e salute. - Alf


1

Un modello di classe è un modello utilizzato per generare classi mentre una classe modello è una classe prodotta da un modello.


0

Classe modello: una classe che ha una definizione generica o una classe con parametri che non viene istanziata fino a quando le informazioni non vengono fornite dal client. Si fa riferimento a un gergo per semplici template. Semplice classe con prefisso template e uso di T. Modello di classe: la costruzione individuale di una classe è specificata da un modello di classe che è quasi simile al modo in cui i singoli oggetti vengono costruiti utilizzando una classe. Si riferisce a un oggetto della classe template Ex- classname nome oggetto (elenco di argomenti)


0

Il modello di classe è una classe generica per diversi tipi di oggetti. Fondamentalmente fornisce una specifica per la generazione di classi basate su parametri. Ogni volta che viene creato un nuovo oggetto, una nuova classe avrà luogo nella memoria a tale scopo. Questa operazione è chiamata creazione di un'istanza di un modello di classe e ogni versione della classe di cui è stata creata un'istanza è chiamata classe modello.


0

Dai un'occhiata a questo documento (dal wg21 ed è stato pubblicato nel 1992) :

Terminologia coerente

La maggior parte dell'argomento e del disaccordo fino ad oggi è stata relativa alla terminologia utilizzata nel capitolo che descrive i modelli. La più frequente è stata l'applicazione variabile di 'modello-funzione' e 'funzione-modello' per esprimere idee e intenti diversi. Poiché non viene applicata alcuna denominazione coerente, il risultato è confusione e argomento.

Ai fini del presente documento, come proposta di adozione formale da parte della commissione nelle discussioni sui modelli e ai fini di chiarimento della documentazione; Propongo di adottare la formalizzazione, che un '-template' finale descrive un insieme di tipi o funzioni descritti da un modello. E che un "modello-" iniziale viene utilizzato per descrivere la definizione del modello di parte di un "modello" , come un 'template-member-function'. Quindi: -

  • 'modello di funzione': un insieme di funzioni descritte da un modello, parametriche su alcune informazioni di tipo fornite come argomento a quel modello. Per esempio :-
template<class T> int nullcheck( T* pT )
{ return ( pT != 0 ); }
  • 'class-template': un insieme di classi descritte da un template, parametriche su alcune informazioni di tipo fornite come argomento a quel template. Per esempio :-
template<class T> class S {
int i;
public:
int sep_member();
int imm_member()
{ return 2; }
}
  • 'template-function': questo termine non è più consentito. **
  • 'template-class': questo termine non è consentito. **

  • 'modello-funzione-membro': questo termine non è consentito, poiché descrive una proprietà non attualmente supportata dalla definizione del modello. Usando la convenzione terminologica sopra, questo descriverebbe un membro di un modello non di classe, la cui definizione era essa stessa un modello. Per esempio :-

class Normal { public:
template<class T> int foo(T*pT)
{ return ( pT == 0 ); }
};

Tuttavia, poiché i modelli sono attualmente limitati all'ambito globale, tale modello non è valido.

  • 'template-static-member-function':
  • 'template-member-function':
  • 'template-static-member':
  • 'template-static-data-member ' template-member ': termini alternativi per la definizione di un membro che appaiono separati dal' class-template 'a cui appartiene. Per esempio :-
template<class T> int S<T>::sep_member()
{ return i; }

Riguardo alla Normalclasse che descrivi sopra: non sapevo che un simile modello di funzione membro fosse proibito. È accettato da tutti i compilatori che ho provato. Cosa mi manca?
dan_din_pantelimon
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.