1

C++ では、次のことができるようにしたいと考えています。

struct IWrapper {
    template<typename U>
    U* dynamic_cast_to() { ??? } // what to do here?
};

template<typename T>
struct Wrapper : IWrapper {
    Wrapper(T* _p) :p(_p) {}    
    T* p;
};

これで私はできるようになりたいです

SomeDerived *a = new SomeDerived;
IWrapper *x = new Wrapper<SomeDerived>(a);
SomeBase *b = x->dynamic_cast_to<SomeBase>()

dynamic_cast_to()SomeDerived実際に継承しSomeBaseている場合はポインタを返す必要がありNULL、そうでない場合は通常の動作と同じようにdynamic_cast動作します。

これは可能ですか?

4

3 に答える 3

1

任意の型 T および U に対してこれを実行できるとは思いません。その理由は、コンパイラがコンパイル時に特定の型のペアに対して dynamic_cast コードを生成する必要があり、両方の型が同時に認識される場所がないためです。コンパイル時間。

仮想メンバー関数を持つ特定のベースから派生した型に対してのみ IWrapper が機能するように制限できる場合、次のように機能します。

struct IWrapper {
    template<typename U>
    U* dynamic_cast_to() { return dynamic_cast<U*>(commonBasePtr()); }

    virtual CommonBase* commonBasePtr() = 0;
};

template<typename T>
struct Wrapper : IWrapper {
    Wrapper(T* _p) :p(_p) {}    
    T* p;

    virtual CommonBase* commonBasePtr() { return p; }
};
于 2013-02-24T18:14:42.057 に答える
1

IWrapper仮想デストラクタを指定して使用しますdynamic_cast

関数を実装する方法について質問されたことに驚いていdynamic_cast_toます。

では、どうすれば標準を考慮することを避けるdynamic_castことができますか?

于 2013-02-24T17:22:18.180 に答える
0

IWrapper は T について何も知らず、ポインターにアクセスできないため、そのようなことはできません。これはうまくいくはずです:

template <typename T>
struct IWrapper {
    IWrapper(T* p) : p_(p) {}
    template<typename U>
    U* dynamic_cast_to() { return dynamic_cast<U*>(p_); }
private:
    T* p_;
};

template<typename T>
struct Wrapper : IWrapper<T> {
    Wrapper(T* _p) : IWrapper<T>(_p), p(_p) {}    
    T* p;
};

struct SomeBase {
    int a;
};

struct SomeDerived : public SomeBase {
    int b;
};

int main()
{
    SomeDerived *a = new SomeDerived;
    IWrapper<SomeDerived> *x = new Wrapper<SomeDerived>(a);
    SomeBase *b = x->dynamic_cast_to<SomeBase>();
    return b->a;
}
于 2013-02-24T18:25:17.273 に答える