1

我正在尝试拥有一个为调用类分配 shared_ptrs 的通用基类/助手类,但我在让它在派生类中工作时遇到了问题。

#include <memory>

template<typename T>
struct SPAlloc {

    virtual ~SPAlloc() {}

    template<typename ...Args>
    static std::shared_ptr<T>
    Alloc(Args&&... params) {
        return std::make_shared<T>(std::forward<Args>(params)...);
    }


    template<class U, typename ...Args>
    static std::shared_ptr<U>
    Alloc(Args&&... params) {
        return std::make_shared<U>(std::forward<Args>(params)...);
    }
};

class Base : public SPAlloc<Base> {
public:
    virtual ~Base() {};
};

class Child : public Base {
public:
    virtual ~Child() {};
};

typedef std::shared_ptr<Base> pBase;
typedef std::shared_ptr<Child> pChild;

int main() {
    pBase base = Base::Alloc();
    pChild child = Child::Alloc();
}

我知道模板中的class Base : public SPAlloc<Base>意思是,这就是我创建第二个 Alloc 的原因。第二个 alloc 需要被称为 like 。TBaseChild::Alloc<Child>()

有没有办法写这个Alloc,以便编译器可以推断出我调用 Alloc 的类?

4

2 回答 2

0

简短的回答:不,没有。

长答案:关键是除非明确告知,否则Alloc不知道Child,那么这些信息来自哪里?对 的调用Child::Alloc()是对 的调用Base::Alloc(),对 的调用是对的调用SPAlloc<Base>::Alloc(),所有关于的信息Child都丢失了。

最简单的解决方案是使用免费函数,但该函数已经存在并且它被称为:std::make_shared。也许考虑直接使用它并完全避免麻烦SPAlloc

或者,如果你想SPAlloc<T>::Alloc()为每个孩子覆盖,你根本不需要基类SPAlloc,只需将方法添加到每个类,这可能比使用基类更容易。

于 2013-03-24T23:24:22.823 回答
0

如果您真的想这样做,您需要将所有对象Spalloc作为模板参数从它们自己继承,甚至是您的子类:

class Child : public SPAlloc<Child>, public Base {
public:
    virtual ~Child() {};
public:
   using SPAlloc<Child>::Alloc;
};

您也可以简单地使用 std::make_shared :)

于 2013-03-24T23:32:16.177 回答