C ++では、子クラスで異なるパラメータ値をパラメータ化基本クラスを拡張することができますか?

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

質問

私はこのことを理解し、すべての言語では可能ではありませんが、誰かがそれはCで可能であった++が、私は苦労それを信じるを持っている私に言いました。あなたは、コンパイル段階で一意のクラスを作成しているクラスをパラメータ化するとき、本質的に、あなたはそうではありませんか?

私は私の質問で明らかされていない午前なら、私に教えてくださいます。

ここで私が何をしようとしています何explaningでの私の試みは(クラス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が長くなるために、その親のフロートパラメータを再定義しようとしています。それは確かにこれは合法であるように見えるしていませんが、私は専門家に異なります。

役に立ちましたか?

解決

あなたがC ++でこれを行うことができるかどうかを尋ねることを意味する場合:

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

[はい、それは可能です。

これは、非常に多くの場合、テンプレートのリストを定義するか、または別のタイプから特性を継承するために、たとえば、使用されます。

他のヒント

何を求めてきましたが、直接実行することはできません - しかし、あなたは、デフォルトのテンプレートパラメータを使用してかなり近づくことができます:

template <typename T>
class Base { };

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

class Y : Base<float>

class Z : X<long> {};

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

#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 :)
}

の継承は、あなたが何かをお願いするものでない限り、一度動作するはず書いたものstephenmm公開され、C ++では、デフォルトでプライベートで?

あなたはテンプレートについては取っていますか?

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

あなたはそれをコンパイルしようとする必要があります:

$ 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におけるテンプレートパラメータが未使用であり、何も上書きされません。

HTH

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top