Come inoltrare dichiarare una classe modello C ++?


99

Data una classe modello come la seguente:

template<typename Type, typename IDType=typename Type::IDType>
class Mappings
{
public:
    ...
    Type valueFor(const IDType& id) { // return value }
    ...
};

Come può qualcuno in avanti dichiarare questa classe in un file di intestazione?

Risposte:


103

Ecco come lo faresti:

template<typename Type, typename IDType=typename Type::IDType>
class Mappings;

template<typename Type, typename IDType>
class Mappings
{
public:
    ...
    Type valueFor(const IDType& id) { // return value }
    ...
};

Si noti che il valore predefinito è nella dichiarazione anticipata e non nella definizione effettiva.


È possibile dichiarare in avanti una classe i cui valori predefiniti sono elencati nella sua definizione. Vedi la mia risposta.
Elliott

Non sono d'accordo. Lo standard dice: "A un parametro-modello non devono essere forniti argomenti di default da due dichiarazioni diverse nello stesso ambito" . E non ho trovato nulla sui valori predefiniti solo nella prima dichiarazione. Anche il codice con la dichiarazione in avanti e le impostazioni predefinite nella definizione viene compilato ed eseguito correttamente. Sei sicuro di ciò che stai rivendicando? Potete fornire un preventivo dallo standard?
olek stolar

@Elliott Sembra che sia vero. Lo standard [17.1.9] dice: "Un modello-argomento predefinito può essere specificato in una dichiarazione di modello." Non deve essere, ma potrebbe esserlo. Quindi non capisco perché altre risposte affermino che dovrebbe essere nella prima dichiarazione.
olek stolar

E sembra molto più conveniente avere valori predefiniti nella definizione.
olek stolar

8

È possibile dichiarare argomenti predefiniti per un modello solo per la prima dichiarazione del modello. Se si desidera consentire agli utenti di inoltrare la dichiarazione di un modello di classe, è necessario fornire un'intestazione di inoltro. Se vuoi inoltrare la dichiarazione del modello di classe di qualcun altro usando i valori predefiniti, sei sfortunato!


È possibile dichiarare in avanti una classe i cui valori predefiniti sono elencati nella sua definizione. Vedi la mia risposta.
Elliott

Non sono d'accordo. Lo standard dice: "A un parametro-modello non devono essere forniti argomenti di default da due dichiarazioni diverse nello stesso ambito" . E non ho trovato nulla sui valori predefiniti solo nella prima dichiarazione. Anche il codice con la dichiarazione in avanti e le impostazioni predefinite nella definizione viene compilato ed eseguito correttamente. Sei sicuro di ciò che stai rivendicando? Potete fornire un preventivo dallo standard?
olek stolar

3

È possibile dichiarare una classe basata su modelli la cui definizione indica gli argomenti predefiniti, ma ogni volta che si fa riferimento alla classe è necessario includere tutti i suoi argomenti finché non viene introdotta la definizione.

per esempio. Usiamo std::vectorsenza includerlo (il secondo argomento di std::vectorè definito con un valore predefinito):

namespace std
{
    template<typename, typename>
    class vector;
}

#include <iostream>

template <typename S, typename T>
void Foo (const std::vector<S,T> & vector)
{
    std::cout << "do vector stuff, eg., display size = "
        << vector.size() << std::endl;
}

template <typename T>
void Foo (const T & t)
{
    std::cout << "do non-vector stuff..." << std::endl;
}

Possiamo quindi usarlo senza includere il vettore, ad es .:

int main()
{
    Foo(3);
}

E possiamo usarlo con std::vector , ad esempio:

#include <vector>

// Now the compiler understands how to handle
// std::vector with one argument
// (making use of its default argument)

int main()
{
    Foo(std::vector<int>(3));
}

Non ho controllato gli standard, ma funziona fino a clang/ gcccon , quindi se non è ufficialmente uno standard, sembra che lo sia in modo non ufficiale.-std=c++98-std=c++17


Forse dimentichi le parentesi angolari vuote Foo<> foo;.
olek stolar

@ OleksijPlotnyc'kyj hai ragione. Grazie. Ho cancellato quell'aggiunta.
Elliott
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.