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

この特定のケースでは、既定のテンプレート パラメーターはあまり追加しません。すべてのパラメータにデフォルトが指定されている場合でも、テンプレートをインスタンス化するには、テンプレート パラメータ リストを指定する必要があります。そのため、派生クラスでオーバーライドするデフォルトを持つことは、通常、2 番目以降のパラメーターにのみ役立ちます。

于 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

コンパイルしてみてください:

$ 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 はクラス テンプレートではないため、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 のテンプレート パラメーターは使用されておらず、何もオーバーライドされていません。

HTH

于 2010-01-05T23:21:31.533 に答える
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 に答える