2017-05-17 23 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と何の関係も持っていません。私は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へのポインタを持っています。実際のタイプはコンパイル時には不明で、テンプレートのメタプログラミング技術は役に立たないと私は考えています。 –

+0

さて、有効なアプローチを見つけようとすることはできますが、多かれ少なかれ実際のケースと似ている最小限の例を質問に入れてください。そうでなければ、解決策が存在するかどうかは言えません。 – skypjack

+0

私は例を追加し、私が直面している実際の問題を少し説明しました。あなたの興味、スカイプジャックありがとう –

関連する問題