如何识别类型以将shared_ptr强制转换为该类型

时间:2015-12-04 10:16:00

标签: c++ templates c++11 shared-ptr

我有一个类层次结构,我想从中共享并将其转换为特定的类类型。所以我想要这个:

class A : public std::enable_shared_from_this
{
    std::shared_ptr<A> getSharedFromThis()
    {
        return std::static_pointer_cast<A>(shared_from_this());
    }
};

class B : public A
{
    std::shared_ptr<B> getSharedFromThis()
    {
        return std::static_pointer_cast<B>(shared_from_this());
    }
};

在超类中我可以写一个模板化的变体,但它仍然不酷:

template <typename T>
std::shared_ptr<T> getSharedFromThis()
{
    return std::static_pointer_cast<T>(shared_from_this());
}

如何使其成为通用的,以便它理解它在类B中并转换为B shared_ptr,现在在100个类中写入相同的逻辑相同的等级。

2 个答案:

答案 0 :(得分:2)

您正在寻找 covariant return type 明智smart pointers。这将是一个很好的功能,但你不能这样做。唯一可行的方法是在shared_ptr<A>shared_ptr<B>之间建立等级关系,在不久的将来情况就不会如此。

您必须坚持使用父类模板或使用能够实现协变返回类型范例的包装器对象(这意味着需要仔细声明并因copypasta而导致错误)。

std::enable_shared_from_this在您的示例中未正确使用,因为它是模板化的类。

如果getter位于父类中,请小心使用dynamic_pointer_cast

答案 1 :(得分:1)

似乎你的关键问题是推断出调用模板getSharedFromThis()的类型。由于成员函数是在基类中实现的,因此它没有任何派生类调用它的痕迹 - 除非以某种方式指定。使用调用基函数的非成员函数将整齐地处理:

template <typename T>
auto getSharedFromThis(T& object) -> decltype(object.template getSharedFromThis<T>()) {
    return object.template getSharedFromThis<T>());
}

这样就不需要为任何派生类编写任何内容来获得getSharedFromThis()函数,从而产生适当的类型std::shared_ptr<T>。作为奖励,具有暴露getSharedFromThis()函数的基础的类似层次结构可以使用相同的功能。您可能希望使用指针类型重载函数,以便在成员函数中使用getSharedFromThis(this)而不是getSharedFromThis(*this)