2017-05-17 8 views
3

주어진 기본 클래스에서 상속받은 모든 포함 된 객체를 검색 할 수있는 형식 삭제 패턴을 만들어야합니다. 지금까지 내가 아는 한 boost :: any와 같은 인기있는 형식 지움은 요청되고 포함 된 클래스가 정확히 일치하는 경우에만 any_cast를 사용하여 객체를 검색 할 수있게하므로 내 필요에 맞지 않습니다.템플릿 인수의 상속 계층

템플릿 인수의 상속 관계를 모방 한 템플릿 클래스의 문제를 해결할 수있었습니다. 이 동작을 달성하기 위해 패턴이

// Suppose all clases have virtual destructors so that vtable and RTTI info are available 

class ObjectWrapperBase { 
} 

template<class DataType> 
class ObjectWrapperT: public ObjectWrapperBase { 
public: 
    ObjectWrapperBase(T* ptr): dataObjPtr(ptr){} 
    DataType *dataObjPtr; 
} 

class Base{} 
class Derived: public Base{} 
class NotDerivedFromBase{} 

int main(){ 

    std::vector<ObjectWrapperBase*> v; 
    v.push_back(new ObjectWrapperT<Base>(new Base)); 
    v.push_back(new ObjectWrapperT<Derived>(new Derived)); 
    v.push_back(new ObjectWrapperT<NotDerivedFromBase>(new NotDerivedFromBase)); 

    // Now suppose I want to retrieve all the Base and children objects in v 
    // If ObjectWrapperT<Derived> is a child of ObjectWrapperT<Base> I can write: 

    for(int i = 0; i < v.size(); i++){ 
    ObjectWrapperT<Base> *wPtr = dynamic_cast<ObjectWrapperT<Base>*>(v[i]); 
    if(wPtr){ 
     Base *basePtr = wPtr->dataObjPtr; 
    } 
    } 
} 

있습니까 : 다음 예제가 작동 할 수 있도록 예를 들어, TemplateClass<Derived>TemplateClass<Base>의 자녀가되어야 하는가? 아니면 결국 또 다른 해결책? 감사합니다. .

+1

만약 내가 틀렸다면 당신의 질문을 올바르게 이해했는지 모르겠다. 당신의'Derived'와'Base'는'TemplateClass'와는 독립적으로 만들어지며 내부의 상속 구조를 알지 못합니다. TemplateClass의. 그렇다면 나는 C++ 타입 특성이 클래스의 직접적인 부모를 얻기위한 인터페이스를 구현하지 않기 때문에 원하는 것을 얻을 수 있다고 생각하지 않는다. –

+0

예, Derived와 Base는 TemplateClass와 관계가 없으므로 TemplateClass와 관련이 없습니다. 또한 C++에서 원하는 것을 얻을 수있는 방법이 없다는 것을 확신하고 있습니다. –

+0

'TemplateClass' 사용자에게'Derived'' Base' 관계의 구조를 결정하게 할 수있는 해결 방법을 찾을 수 있습니다 예 사용자가'TemplateClass'와 함께 상속 구조를 공유 할 수있게 해주는'TemplateClass'에서 알려진 커스텀 특성을 제공합니다. 그러나 솔직히 나는 이것이 당신이 정말로 찾고있는 것인지 확신하지 못합니다. [예] (https://wandbox.org/permlink/FjScqN7hDAEwfSBc) –

답변

0

당신이 찾고 있지만, 이런 식으로 뭔가 할 수있는 일이면 나도 몰라 :

template <typename T> 
class Derived : public T 
{ 

}; 

을 그리고 다음과 같이 Base라는 어머니의 클래스를 인스턴스화 :

Derived<Base> object; 

당신은 마지막으로 Base에서이를 얻을 것이다 :

class Derived : public Base 
{ 

}; 
1

요 원하는 것을 정확히 할 수는 없지만 템플릿과 운영자에게 더 가까이 다가 갈 수는 있습니다. 최소한, 작업 예를 들어
: 마지막 라인에 주석을 전환하는 경우

#include<type_traits> 

template<typename D> 
struct S { 
    S(D *d): d{d} {} 

    template<typename B, typename = std::enable_if_t<std::is_base_of<B, D>::value>> 
    operator S<B>() { 
     return {d}; 
    } 

private: 
    D *d; 
}; 

struct B {}; 
struct D: B {}; 
struct A {}; 

int main() { 
    S<D> sd{new D}; 
    S<B> sb = sd; 
    // S<A> sa = sd; 
} 

, 그것은 더 이상 A에 대한 컴파일되지 B의 기본은 아닙니다.

+0

감사합니다. 작동하지만 달성하고자하는 것은 아닙니다. 사실 나는 그 상황을 지나치게 단순화했을지도 모른다. 실제로, TemplateClass는 템플릿 인자 클래스의 객체의 인스턴스를 가지고있는 타입 삭제 패턴의 자리 표시 자입니다. TemplateClass는 다른 비 템플릿 클래스의 하위 클래스이며 ClassBase라고하며 런타임에는 알 수없는 템플릿 매개 변수가있는 TemplateClass의 특수화에 속하는 TemplateClass 객체를 가리키는 ClassBase에 대한 포인터가 있습니다. 그래서 실제 타입은 컴파일 타임에 알려지지 않았습니다. 그리고 저는 템플릿 metaprogramming 기법이 도움이 될 수 없다고 생각합니다. –

+0

글쎄, 나는 유효한 접근법을 찾아 내려고 노력할 수도 있지만, 질문에 실제 사례와 거의 비슷하게 보이는 최소한의 예를 넣어야한다. 그렇지 않으면 해결책이 존재하는지 말할 수 없습니다. – skypjack

+0

예제를 추가하고 내가 직면 한 실제 문제를 약간 설명했습니다. 관심을 가져 주셔서 감사합니다, 스킵 잭 –