C++에서 하위 클래스의 다른 매개변수 값을 사용하여 매개변수화된 기본 클래스를 확장할 수 있습니까?

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

문제

내가 이해하는 모든 언어에서는 이것이 불가능하지만 누군가 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으로 재정의하려고 합니다.확실히 이것이 합법적인 것 같지는 않지만 전문가의 의견은 다릅니다.

도움이 되었습니까?

해결책

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

상속은 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는 클래스 템플릿이 아니므로 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