In C ++ si può estendere una classe di base parametrizzato con diverso valore di parametro nella classe del bambino?

StackOverflow https://stackoverflow.com/questions/2009295

Domanda

In tutte le lingue che ho capito questo non è possibile, ma qualcuno mi diceva che era possibile in C ++, ma ho difficoltà a crederci. In sostanza quando si parametrizzare una classe che si sta creando una classe unica in fase di compilazione non è vero?

Fatemi sapere se io non sto essendo chiaro con la mia domanda.

Qui è il mio tentativo di explaning quello che sto cercando di fare (prestare attenzione alla classe L):

//; g++ ModifingBaseClassParameter.cpp -o ModifingBaseClassParameter;ModifingBaseClassParameter

#include <iostream>

using namespace std;

template<typename T>
class Base
{
    public:
        Base() {}
        Base(T& t) : m_t(t) {}
        T& getMem() {return m_t;}
    private:
        T m_t;
};

template<typename T>
class F: Base<T>
{};

template<typename T>
class L: F<long>
{};

int main()
{
     Base<int> i;
     F<float> f;
     L<long> l;

     cout<<i.getMem()<<endl;
//     cout<<f.getMem()<<endl; // why doesn't this work
//     cout<<l.getMem()<<endl; // why doesn't this work
}

Quindi, come potete vedere (si spera la mia sintassi ha senso) classe L sta cercando di ridefinire il parametro flottante del suo genitore per essere una lunga. Certamente non sembra come questo è legale, ma sarà diverso agli esperti.

È stato utile?

Soluzione

Se hai intenzione di chiedere se si può fare questo in C ++:

template <> 
class ParamClass<Type1> : public ParamClass<Type2> 
{
};

allora sì, è possibile.

E 'molto spesso usato, ad esempio per definire le liste di template o ereditare tratti da un altro tipo.

Altri suggerimenti

Quello che hai chiesto non può essere fatto direttamente - ma si può venire abbastanza vicino utilizzando un parametro di modello predefinito:

template <typename T>
class Base { };

template <typename T = int>
class X : Base<T> {};

class Y : Base<float>

class Z : X<long> {};

In questo caso particolare, il parametro di template di default non aggiunge molto. È necessario fornire una lista di parametri modello per creare un'istanza di un modello, anche se di default sono forniti per tutti i parametri. In quanto tale, avendo un default che si ignora in una classe derivata di solito è utile solo per la seconda e successive parametri.

#include <iostream>
#include <typeinfo>

using namespace std;

template<typename T>
class Base
{
    public:
        Base() {}
        Base(T& t) : m_t(t) {}
        T& getMem() {return m_t;}
    private:
        T m_t;
};

template<typename T>
class F: public Base<T>
{};

template<typename T>
class L: public F<long>
{};

int main()
{
     Base<int> iNTEGER;
     F<float> fLOAT;
     L<long> lONG;

     int x;
     cout << typeid(iNTEGER.getMem()).name() << endl;
     cout << typeid(fLOAT.getMem()).name() <<endl; // this works now :)
     cout << typeid(lONG.getMem()).name() <<endl; // this works now :)
}

l'eredità è privato di default in C ++, una volta reso pubblico ciò che ha scritto stephenmm dovrebbe funzionare a meno che non si intende chiedere qualcos'altro?

Stai prendendo sui modelli?

template<typename T>
class Base
{
    public:
        Base() {}
        Base(T& t) : m_t(t) {}
        T& getMem() {return m_t;}
    private:
        T m_t;
};

class X: Base<int>
{};

class Y: Base<float>
{};

Si dovrebbe provare a compilarlo:

$ g++ so-test1.c++ -o so-test1.c++ && ./so-test
so-test1.c++:21: error: expected template-name before ‘<’ token
so-test1.c++:21: error: expected `{' before ‘<’ token
so-test1.c++:21: error: expected unqualified-id before ‘<’ token
so-test1.c++: In function ‘int main(int, const char**)’:
so-test1.c++:27: error: aggregate ‘Z z’ has incomplete type and cannot be defined

X non è un modello di classe, quindi non ha senso cercare di un'istanza in

class Z: X<long> {};

X non ha parametri di modello per ignorare. Ricorda che

Base<int>

non è un modello di classe sia; è una classe a sé stante, ma completamente un'istanza da un modello. Si potrebbe fare questo:

....
template<typename T>
class X: Base<T> 
{};
...
class Z: X<long> 
{};

Ma qui non c'è confusione su sovrascrivendo eventuali parametri di modello.

template<typename T>
class X: Base<int> 
{};
...
class Z: X<long>
{};

lavora troppo, ma qui il parametro di template in X è inutilizzato, e nulla viene ignorata.

HTH

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top