В C ++ вы можете расширить параметризованный базовый класс с другим значением параметра в дочернем классе? - PullRequest
0 голосов
/ 06 января 2010

На всех языках, которые я понимаю, это невозможно, но кто-то говорил мне, что это возможно в C ++, но мне трудно поверить в это. По сути, когда вы параметризируете класс, вы создаете уникальный класс на этапе компиляции, не так ли?

Дайте мне знать, если мне не ясен мой вопрос.

Вот моя попытка объяснить, что я пытаюсь сделать (обратите внимание на класс 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
}

Итак, как вы можете видеть (надеюсь, мой синтаксис имеет смысл), класс L пытается переопределить параметр float своего родителя, чтобы он был длинным. Это, конечно, не кажется законным, но я буду отличаться от экспертов.

Ответы [ 5 ]

2 голосов
/ 06 января 2010

То, что вы просили, не может быть выполнено напрямую, но вы можете подойти довольно близко, используя параметр шаблона по умолчанию:

template <typename T>
class Base { };

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

class Y : Base<float>

class Z : X<long> {};

В этом конкретном случае параметр шаблона по умолчанию не добавляет много. Вы должны предоставить список параметров шаблона для создания экземпляра шаблона, даже если для всех параметров предусмотрены значения по умолчанию. Таким образом, наличие значения по умолчанию, которое вы переопределяете в производном классе, обычно полезно только для второго и последующих параметров.

2 голосов
/ 06 января 2010

Если вы хотите спросить, можете ли вы сделать это в c ++:

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

тогда да, это возможно.

Он очень часто используется, например, для определения списков шаблонов или наследования признаков от другого типа.

1 голос
/ 15 мая 2012
#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 :)
}

наследование является закрытым по умолчанию в c ++, однажды сделанное общедоступным то, что написал Стивенм, должно работать, если вы не хотели спросить что-то еще?

0 голосов
/ 06 января 2010

Вы должны попробовать скомпилировать его:

$ 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 не является шаблоном класса, поэтому нет смысла пытаться создать его экземпляр в

class Z: X<long> {};

X не имеет параметров шаблона для переопределения. Помните, что

Base<int>

тоже не шаблон класса; это класс сам по себе, но полностью создан из шаблона. Вы могли бы сделать это:

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

Но здесь нет путаницы при переопределении любых параметров шаблона.

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

тоже работает, но здесь параметр шаблона в X не используется, и ничего не переопределяется.

НТН

0 голосов
/ 06 января 2010

Вы беретесь за шаблоны?

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>
{};
...