0

在我理解的所有语言中,这是不可能的,但有人告诉我这在 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 参数重新定义为 long。这当然看起来不合法,但我会与专家不同。

4

5 回答 5

2

如果您要问是否可以在 c++ 中执行此操作:

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

那么是的,这是可能的。

它经常被使用,例如定义模板列表或从其他类型继承特征。

于 2010-01-05T21:48:47.410 回答
2

你所要求的不能直接完成——但你可以通过使用默认模板参数来非常接近:

template <typename T>
class Base { };

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

class Y : Base<float>

class Z : X<long> {};

在这种特殊情况下,默认模板参数不会增加太多。即使为所有参数提供了默认值,您也必须提供模板参数列表来实例化模板。因此,在派生类中覆盖默认值通常仅对第二个和后续参数有用。

于 2010-01-05T23:35:41.930 回答
1
#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++ 中是私有的,一旦公开,stephenmm 所写的内容应该可以工作,除非你想问别的?

于 2012-05-15T07:29:50.660 回答
0

你在考虑模板吗?

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>
{};
于 2010-01-05T21:44:27.710 回答
0

你应该尝试编译它:

$ g++ so-test1.c++ -o so-test1.c++ && ./so-test
so-test1.c++:21: error: expected template-name before ‘&lt;’ token
so-test1.c++:21: error: expected `{' before ‘&lt;’ token
so-test1.c++:21: error: expected unqualified-id before ‘&lt;’ 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 中的模板参数未使用,并且没有任何内容被覆盖。

高温高压

于 2010-01-05T23:21:31.533 回答