2010-12-18 10 views
12

파생 클래스를 템플릿 클래스의 자손으로 사용합니다. 그 클래스는 자손의 멤버에 의존합니다.기본 클래스의 파생 클래스 'typedef 사용

struct IBootParams 
{ 
    virtual bool GetImmediate() = 0; 
}; 

template <class T> 
struct TBootBootParams 
{ 
    typename T::TransType transferType; 

    typename T::UseAbort_ useAbort; 

    bool GetImmediate() 
    { 
     if (transferType == T::e1) 
     { 
      return useAbort.someFlag; 
     } 

     return false; 
    } 

}; 

struct BootBootParams : public TBootBootParams<BootBootParams> 
{ 
    enum SomeEnum 
    { 
     e1=0, 
     e2, 
     e3 
    }; 

    struct UseAbort 
    { 
     bool  someFlag;   

     char  someMember;    
     int   otherMember;   
    } useAbort; 

    typedef SomeEnum TransType; 
    typedef UseAbort UseAbort_; 
}; 

struct BootAltBootParams : public TBootBootParams<BootAltBootParams> 
{ 
    enum SomeEnum 
    { 
     e1=5, 
     e2, 
     e3 
    }; 

    struct UseAbort 
    { 
     bool  someFlag;   

     long long  someMember;    
     long long  otherMember;   
    } useAbort; 

    typedef SomeEnum TransType; 
    typedef UseAbort UseAbort_; 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    BootBootParams bp; 
    BootAltBootParams bpa; 

    bool f = bp.GetImmediate(); 
    f = bpa.GetImmediate(); 
} 
+0

그래서 무엇이 오류입니까? – ybungalobill

+2

왜 IBootParams를 선언 했습니까? –

답변

10

이렇게하면 안됩니다. 컴파일러가 TBootBootParams<BootBootParams>을 인스턴스화하면 BootBootParams의 전체 정의를 아직 읽지 못해 TBootBootParams 정의 내부에서 멤버에 액세스 할 수 없습니다. TBootBootParams의 멤버 함수는 나중에 인스턴스화되기 때문에 예외입니다.

template<class T> struct TBootBootParams_traits; 

template <class T> 
struct TBootBootParams 
{ 
    typename TBootBootParams_traits<T>::TransType transferType; 

    typename TBootBootParams_traits<T>::UseAbort_ useAbort; 

    bool GetImmediate() 
    { 
     if (transferType == TBootBootParams_traits<T>::e1) 
     { 
      return useAbort.someFlag; 
     } 

     return false; 
    } 

}; 

struct BootBootParams; 
template<> struct TBootBootParams_traits<BootBootParams> 
{ 
    enum SomeEnum 
    { 
     e1=5, 
     e2, 
     e3 
    }; 

    struct UseAbort 
    { 
     bool  someFlag;   

     long long  someMember;    
     long long  otherMember;   
    }; 

    typedef SomeEnum TransType; 
    typedef UseAbort UseAbort_; 
}; 

struct BootBootParams : 
    public TBootBootParams<BootBootParams>, 
    public TBootBootParams_traits<BootBootParams> 
{ 
    UseAbort_ useAbort; 
}; 
+0

이것은 내가 생각하는 것보다 나은 해킹입니다. 조금 깔끔해. – Omnifarious

+0

멋진데. 나는 왜'template <> struct TBootBootParams_traits' 선언에 forward 선언문이있는 동안'<>'내에 타입 매개 변수가 없는지 이해할 수 없습니다. –

+1

@ Sergey : 전문 분야이기 때문에. @All + @Omnifarious : 일부 템플릿에 일부 매개 변수를 전달하는 표준 방법입니다. 예 : STL은 iterator (iterator_traits)에이를 사용합니다. – ybungalobill

4

이 그 해킹의 비트 아닌 작업 할 수있는 방법이 없다 : 는 한마디로이 코드를 컴파일합니다.

struct IBootParams 
{ 
    virtual bool GetImmediate() = 0; 
}; 

template <class T> 
struct TBootBootParams : public IBootParams 
{ 
    typename T::TransType transferType; 

    typename T::UseAbort_ useAbort; 

    virtual bool GetImmediate() 
    { 
     if (transferType == T::e1) 
     { 
      return useAbort.someFlag; 
     } 

     return false; 
    } 

}; 

struct BootBootParams_types 
{ 
    enum SomeEnum 
    { 
     e1=0, 
     e2, 
     e3 
    }; 

    struct UseAbort 
    { 
     bool  someFlag; 

     char  someMember; 
     int   otherMember; 
    } useAbort; 

    typedef SomeEnum TransType; 
    typedef UseAbort UseAbort_; 
}; 

struct BootBootParams : public BootBootParams_types, 
         public TBootBootParams<BootBootParams_types> 
{ 
}; 

struct BootAltBootParams_types 
{ 
    enum SomeEnum 
    { 
     e1=5, 
     e2, 
     e3 
    }; 

    struct UseAbort 
    { 
     bool  someFlag; 

     long long  someMember; 
     long long  otherMember; 
    } useAbort; 

    typedef SomeEnum TransType; 
    typedef UseAbort UseAbort_; 
}; 

struct BootAltBootParams : public BootAltBootParams_types, 
          public TBootBootParams<BootAltBootParams_types> 
{ 
}; 

int main(int argc, const char * argv[]) 
{ 
    BootBootParams bp; 
    BootAltBootParams bpa; 

    bool f = bp.GetImmediate(); 
    f = bpa.GetImmediate(); 
} 
+1

+1했기 때문에 닫기 : – ybungalobill

+1

고마워요. 흥미 롭 군! – Romeno

0

이 방법을 사용하면 부모 클래스의 구성원으로 템플릿 클래스의 객체를 포함 할 필요가 작동하는 경우 : 그래서 여기에 해킹의 비트에서 내 시도이다.

2

이 당신이 원하는 일을합니까 :

일반적인 솔루션은 특성 클래스를 가지고있다?

struct IBootParams 
{ 
    virtual bool GetImmediate() = 0; 
}; 

template <class T> 
struct TBootBootParams 
{ 
    bool GetImmediate() 
    { 
     if (static_cast<T*>(this)->transferType == T::e1) 
     { 
      return static_cast<T*>(this)->useAbort.someFlag; 
     } 

     return false; 
    } 

}; 

struct BootBootParams : public TBootBootParams<BootBootParams> 
{ 
    enum SomeEnum 
    { 
     e1=0, 
     e2, 
     e3 
    } transferType; 

    struct UseAbort 
    { 
     bool  someFlag;   

     char  someMember;    
     int   otherMember;   
    } useAbort; 
}; 

struct BootAltBootParams : public TBootBootParams<BootAltBootParams> 
{ 
    enum SomeEnum 
    { 
     e1=5, 
     e2, 
     e3 
    } transferType; 

    struct UseAbort 
    { 
     bool  someFlag;   

     long long  someMember;    
     long long  otherMember;   
    } useAbort; 
}; 

int main(void) 
{ 
    BootBootParams bp; 
    BootAltBootParams bpa; 

    bool f = bp.GetImmediate(); 
    f = bpa.GetImmediate(); 
} 
+0

와우. 나는 정말로 감명 받았다. 컴파일해야합니까? 실제로 효과가 있다고해서 그것이 의미하는 것은 아닙니다. :-) – Omnifarious

+0

BTW, gcc 4.5에서도 컴파일됩니다. – Omnifarious

+0

@Omnifarious : 예, 컴파일해야하며 간단합니다. 문제를 일으키는 기본 클래스 멤버를 제거했습니다. 데이터 유형이 파생 된 유형에 의해 결정 되었기 때문에 파생 유형에서 선언 될 수 있으며 기본 클래스는 템플릿 매개 변수를 사용하여 정상적으로 액세스 할 수 있습니다. . –

1

It compiles. 나는 내 자신의 요구를 계산 ybungalobill의 솔루션에 약간의 변화를 시도했다. 그리고이 나는이 모든 유형의 데이터를 배치하는이 클래스의 다른 클래스의 필수이 옵션으로 템플릿 클래스를 사용 .. 요약

template<class T> 
struct TBootBootParams_traits; 

template <class T> 
struct TBootBootParams 
{ 
    typedef TBootBootParams_traits<T> Traits; 

    typename Traits::TransType transferType; 
    typename Traits::UseAbort_ useAbort; 

    bool GetImmediate() 
    { 
     if (transferType == TBootBootParams_traits<T>::e1) 
     { 
      return useAbort.someFlag; 
     } 

     return false; 
    } 
}; 

struct BootBootParams; 
struct BootAltBootParams; 

template<> 
struct TBootBootParams_traits<BootBootParams> 
{ 
    enum SomeEnum 
    { 
     e1=5, 
     e2, 
     e3 
    }; 

    struct UseAbort 
    { 
     bool  someFlag;   

     long long  someMember;    
     long long  otherMember;   
    }; 

    typedef SomeEnum TransType; 
    typedef UseAbort UseAbort_; 
}; 

template<> 
struct TBootBootParams_traits<BootAltBootParams> 
{ 
    enum SomeEnum 
    { 
     e1=5, 
     e2, 
     e3 
    }; 

    struct UseAbort 
    { 
     bool  someFlag;   

     int someMember;    
     float otherMember;   
    }; 

    typedef SomeEnum TransType; 
    typedef UseAbort UseAbort_; 
}; 

struct BootBootParams : 
    public TBootBootParams<BootBootParams> 
{ 

}; 

struct BootAltBootParams : 
    public TBootBootParams<BootAltBootParams> 
{ 

}; 

int main(void) 
{ 
    BootBootParams bp; 
    BootAltBootParams bpa; 

    bool f = bp.GetImmediate(); 
    f = bpa.GetImmediate(); 
} 

을 가지고 무엇을. 이것은 내가 필요한 것입니다. 옵션에 다시 한번 감사드립니다!

관련 문제