Argomenti predefiniti del modello


151

Se mi è permesso fare quanto segue:

template <typename T = int>
class Foo{
};

Perché non mi è permesso fare quanto segue in linea di massima?

Foo me;

Ma devo specificare quanto segue:

Foo<int> me;

C ++ 11 ha introdotto argomenti di template predefiniti e in questo momento sono sfuggenti alla mia completa comprensione.

Risposte:


188

Devi fare:

Foo<> me;

Gli argomenti del modello devono essere presenti ma è possibile lasciarli vuoti.

Pensalo come una funzione foocon un singolo argomento predefinito. L'espressione foonon lo chiamerà, ma lo foo()farà. La sintassi dell'argomento deve essere ancora lì. Questo è coerente con quello.


4
@Pubby Suppongo che creerebbe alcune complicazioni inutili se Foo potrebbe essere un identificatore di modello o potrebbe essere un'istanza esplicita a seconda che esista un argomento predefinito. Meglio mantenere la sintassi di istanza esplicita. Pensalo come una funzione foocon un singolo parametro predefinito. Non puoi chiamarlo come foo, lo chiami con foo(). Ha senso mantenerlo coerente.
Joseph Mansfield,

2
@sftrabbit ma non puoi chiamare una funzione senza argomenti come fooentrambi; puoi nominare una classe senza argomenti come Foocomunque.
Seth Carnegie,

4
@aschepler Con una funzione, gli argomenti del modello possono essere dedotti dagli argomenti della funzione. Con una classe, non è possibile decidere se si intendesse una classe modello con argomenti predefiniti o una classe non modello.
Olaf Dietsche,

21
@OlafDietsche ma non puoi avere una classe template e una classe non template con lo stesso nome, quindi il compilatore dovrebbe essere in grado di decidere semplicemente guardando come si chiama.
Seth Carnegie,

7
@Pubby Il comitato standard si è chiesto lo stesso, credo. Ora, con C ++ 17, <>non è più necessario in questo caso. Controlla la mia risposta per maggiori dettagli.
Paolo M,

53

Con C ++ 17, puoi davvero.

Questa funzione è chiamata deduzione dell'argomento del modello di classe e aggiunge maggiore flessibilità al modo in cui è possibile dichiarare variabili di tipi basati su modelli .

Così,

template <typename T = int>
class Foo{};

int main() {
    Foo f;
}

è ora un codice C ++ legale .


5
Strano. L'ho appena provato nel mio progetto C ++ 17 e non ha funzionato: "tipo segnaposto modello 'const MyType' deve essere seguito da un semplice ID dichiaratore". Sto usando GCC 7.3.0.
Silicomancer,

1
@Silicomancer È difficile dirlo senza vedere il codice e la riga di comando ... Forse hai a che fare con puntatori come qui ?
Paolo M,


1
@Borgleader Apparentemente, Coliru sta usando clang 5.0. A giudicare da ciò , dovrebbe supportare la deduzione dell'argomento del modello C ++ 17, ma evidentemente non lo è. Se provi il tuo stesso esempio in wandbox usando clang 7.0, funziona perfettamente.
Paolo M,

2
@PaoloM Oh bello, felice di sapere che è solo un problema di versione del compilatore. Grazie per aver esaminato questo.
Borgleader,

19

Non ti è permesso farlo, ma puoi farlo

typedef Foo<> Fooo;

e poi fallo

Fooo me;

c'è qualche differenza in questo con un tipo predefinito e:, typedef Foo<float> Fooo;senza un tipo predefinito?
qrikko,

5
Il modo C ++ 11-ish sarebbe direusing Fooo = Foo<>;
Adrian W

18

È possibile utilizzare quanto segue:

Foo<> me;

E intsii il tuo argomento modello. Le parentesi angolari sono necessarie e non possono essere omesse.


Ha senso e grazie ma, come indicato di seguito, perché il tipo specificato non deve essere presente?
user633658

@ user633658: intendevi "identificatore di tipo"? Non sono sicuro di aver capito
Andy Prowl del

Ad ogni modo, riguardo al motivo dietro la necessità di parentesi angolari vuote, posso solo fare congetture, e sono tutte sull'escludere possibili ambiguità con l'uso del solo nome del modello, ma devo confessare che non conosco l'esatto motivo
Andy Prowl

Sospetto fortemente che il requisito per <> sia di abilitare il parser del compilatore per determinare che ti stai riferendo a una classe basata sul modello chiamata foo, piuttosto che a qualcos'altro chiamato foo.
Mac
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.