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

给出IWrapper一个虚拟析构函数并使用dynamic_cast.

我很惊讶这个问题被问到,如何实现一个dynamic_cast_to功能。

那么如何避免考虑标准dynamic_cast呢?

于 2013-02-24T17:22:18.180 回答
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 回答
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 回答